wp_json_encode( mixed $value, int $flags = 0, int $depth = 512 ): string|false
- Since
- 4.1.0, 5.3.0, 6.5.0
- Source
wp-includes/functions.php:4443
Serializes PHP data into a JSON string using json_encode(), then retries with a UTF-8 sanity check if the first pass fails. Useful for building AJAX payloads or inline script data from post arrays, objects, or associative arrays. Returns false, not an empty string, when encoding cannot succeed even after the retry, so check the return value with a strict comparison rather than truthiness.
Compatibility
- WordPress
- since 6.5.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$valuemixed- Variable (usually an array or object) to encode as JSON.
$flagsintoptional- Options to be passed to json_encode(). Default 0.Default:
0 $depthintoptional- Maximum depth to walk through $value. Must be greater than 0. Default 512.Default:
512
Return value
string|false- The JSON encoded string, or false if it cannot be encoded.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Encode a post's fields as JSON for an admin-ajax response
Build a small array from an existing post and its meta, then encode it for output.
$post = get_post( 2 );
$payload = array(
'id' => $post->ID,
'title' => $post->post_title,
'price' => get_post_meta( $post->ID, 'price', true ),
);
$json = wp_json_encode( $payload );
if ( false === $json ) {
echo 'Could not encode payload.';
} else {
echo esc_html( $json );
}Pretty-print a nested array of post titles for debugging
Pass the JSON_PRETTY_PRINT flag so the encoded output is readable when printed to the page.
$titles = array();
foreach ( array( 1, 2, 3 ) as $post_id ) {
$titles[] = get_the_title( $post_id );
}
$json = wp_json_encode( array( 'titles' => $titles ), JSON_PRETTY_PRINT );
echo '<pre>' . esc_html( $json ) . '</pre>';JSON_PRETTY_PRINT is passed straight through to json_encode() as the $flags argument.
Common problems and fixes · 4
- Why does wp_json_encode return false for an array that looks fine?
- What does wp_json_encode do differently from plain json_encode?
- How do I stop deeply nested data from breaking the JSON output?
- Is it safe to echo the result of wp_json_encode directly into an HTML attribute?
Why does wp_json_encode return false for an array that looks fine?
What does wp_json_encode do differently from plain json_encode?
How do I stop deeply nested data from breaking the JSON output?
Is it safe to echo the result of wp_json_encode directly into an HTML attribute?
Alternatives and related functions
json_encode- When you are outside the WordPress bootstrap or don't need the UTF-8 sanity-check fallback that wp_json_encode adds.
wp_send_json- When the encoded value is the entire body of an admin-ajax or REST response, since it also sets the Content-Type header and ends the request.
wp_send_json_success- When you're returning a successful AJAX result and want the standard success wrapper instead of hand-building the array.
json_decode- When you need to turn a JSON string back into a PHP array or object rather than encode one.
Performance profile
How much work a call to wp_json_encode() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Trivial
- Scaling
- Constant
- Instructions
- 12–23
- Plugin surface
- None
- Called by
- 50
Touches nothing outside its own arguments.
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 26.
Nothing here hands control to plugin code.
50 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- serializeserialisation
json_encode()called directly
Further down the call graph this can also reach option, hook, cache, query and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 2 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_json_encode() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
$json !== false | 12 | json_encode() |
$json === false | 23 | json_encode(), _wp_json_sanity_check(), json_encode() |
Across PHP versions
Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 26 instructions, 12–23 executed per call, 1 branch. The work does not change between versions.
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Uses · 1
- _wp_json_sanity_check()Performs confidence checks on data that shall be encoded to JSON.
Used by · 50
- WP_Application_Passwords_List_Table::print_js_template_row()Prints the JavaScript template for the new row item.
- WP_Community_Events::maybe_log_events_response()Logs responses to Events API requests.
- WP_Customize_Date_Time_Control::content_template()Renders a JS template for the content of date time control.
- WP_Customize_Manager::customize_pane_settings()Prints JavaScript settings for parent window.
- WP_Customize_Manager::customize_preview_settings()Prints JavaScript settings for preview frame.
- WP_Customize_Manager::save_changeset_post()Saves the post for the loaded changeset.
- WP_Customize_Manager::wp_die()Custom wp_die wrapper. Returns either the standard message for UI or the Ajax message.
- WP_Customize_Nav_Menus::enqueue_scripts()Enqueues scripts and styles for Customizer pane.
- WP_Customize_Nav_Menus::export_preview_data()Exports data from PHP to JS.
- WP_Customize_Nav_Menus::filter_wp_nav_menu()Prepares wp_nav_menu() calls for partial refresh.
- WP_Customize_Selective_Refresh::export_preview_data()Exports data in preview after it has finished rendering so that partials can be added at runtime.
- WP_Customize_Site_Icon_Control::content_template()Renders a JS template for the content of the site icon control.
Show all 50
- WP_Customize_Widgets::enqueue_scripts()Enqueues scripts and styles for Customizer panel and export data to JavaScript.
- WP_Customize_Widgets::export_preview_data()Communicates the sidebars that appeared on the page at the very end of the page, and at the very end of the wp_footer,
- WP_Customize_Widgets::filter_dynamic_sidebar_params()Inject selective refresh data attributes into widget container elements.
- WP_Interactivity_API::add_load_on_client_navigation_attribute_to_script_modules()Adds the `data-wp-router-options` attribute to script modules that support client-side navigation.
- WP_Interactivity_API::data_wp_bind_processor()Processes the `data-wp-bind` directive.
- WP_Internal_Pointers::print_js()Prints the pointer JavaScript data.
- WP_List_Table::_js_vars()Sends required variables to JavaScript land.
- WP_List_Table::ajax_response()Handles an incoming ajax request (called from admin-ajax.php)
- WP_Privacy_Policy_Content::notice()Adds a notice with a link to the guide when editing the privacy policy page.
- WP_REST_Font_Faces_Controller::prepare_item_for_database()Prepares a single font face post for creation.
- WP_REST_Font_Families_Controller::prepare_item_for_database()Prepares a single font family post for create or update.
- WP_REST_Global_Styles_Controller::prepare_item_for_database()Prepares a single global styles config for update.
- WP_REST_Server::json_error()Retrieves an appropriate error representation in JSON.
- WP_REST_Server::serve_request()Handles serving a REST API request.
- WP_Script_Modules::print_import_map()Prints the import map using a script tag with a type="importmap" attribute.
- WP_Script_Modules::print_script_module_data()Print data associated with Script Modules.
- WP_Script_Modules::print_script_module_translations()Prints translations for all enqueued script modules.
- WP_Scripts::localize()Localizes a script, only if the script has already been added.
- WP_Site_Health::wp_cron_scheduled_check()Runs the scheduled event to check and update the latest site health status for the website.
- WP_Style_Engine_Processor::combine_rules_selectors()Combines selectors from the rules store when they have the same styles.
- WP_Themes_List_Table::_js_vars()Send required variables to JavaScript land
- WP_Widget_Archives::widget()Outputs the content for the current Archives widget instance.
- WP_Widget_Categories::widget()Outputs the content for the current Categories widget instance.
- WP_Widget_Custom_HTML::enqueue_admin_scripts()Loads the required scripts and styles for the widget control.
- WP_Widget_Media_Audio::enqueue_admin_scripts()Loads the required media files for the media manager and scripts for media widgets.
- WP_Widget_Media_Gallery::enqueue_admin_scripts()Loads the required media files for the media manager and scripts for media widgets.
- WP_Widget_Media_Image::enqueue_admin_scripts()Loads the required media files for the media manager and scripts for media widgets.
- WP_Widget_Media_Video::enqueue_admin_scripts()Loads the required scripts and styles for the widget control.
- WP_Widget_Text::enqueue_admin_scripts()Loads the required scripts and styles for the widget control.
- _WP_Editors::default_settings()Returns the default TinyMCE settings.
- _WP_Editors::editor_settings()
- _WP_Editors::wp_mce_translation()Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n(), or as JS snippet that should run after tinymce.js is loaded.
- _json_wp_die_handler()Kills WordPress execution and displays JSON response with an error message.
- _jsonp_wp_die_handler()Kills WordPress execution and displays JSONP response with an error message.
- _print_emoji_detection_script()Prints inline Emoji detection script.
- _wp_ajax_menu_quick_search()Prints the appropriate response to a menu quick search.
- _wp_customize_loader_settings()Adds settings for the customize-loader script.
- _wp_enqueue_auto_register_blocks()Exposes blocks with autoRegister flag for ServerSideRender in the editor.
Source code
function wp_json_encode( $value, $flags = 0, $depth = 512 ) { $json = json_encode( $value, $flags, $depth ); // If json_encode() was successful, no need to do more confidence checking. if ( false !== $json ) { return $json; } try { $value = _wp_json_sanity_check( $value, $depth ); } catch ( Exception $e ) { return false; } return json_encode( $value, $flags, $depth );}Changelog
Introduced in 4.1.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
$data parameter has been renamed to $value and the $options parameter to $flags for parity with PHP.from the docblockAbout this page
- Parsed data
- Generated from the wordpress-develop 7.1.0 tag, from
src/wp-includes/functions.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.