Most WordPress developers use json_encode() without thinking about it. It usually works. But there's a reason WordPress ships its own wrapper.
The difference
json_encode() is native PHP. wp_json_encode() is a WordPress wrapper that does a few extra things.
// Native PHP
echo json_encode( $data );
// WordPress
echo wp_json_encode( $data );On the surface, same output. Under the hood, not quite.
What wp_json_encode() actually does
First, it sets JSON_UNESCAPED_UNICODE by default. Native json_encode() escapes non-ASCII characters as `\uXXXX` sequences. This causes issues with Arabic, Hebrew, Chinese, or any non-Latin content.
$data = [ 'name' => 'محمد' ];
// json_encode output:
// {"name":"محمد"}
// wp_json_encode output:
// {"name":"محمد"}Second, it handles encoding failures. If json_encode() fails on bad input, it returns false silently. wp_json_encode() returns false too, but it also triggers a _doing_it_wrong() notice in debug mode so you actually catch the problem.
Third, it strips invalid UTF-8 bytes before encoding. Native json_encode() will fail or produce garbage output on invalid UTF-8 strings. This happens more often than expected when dealing with user input, database content, or third-party API responses.
Real example
$data = [
'title' => get_the_title(),
'content' => get_post_field( 'post_content', $post_id ),
];
// Risky: fails silently on bad characters
header( 'Content-Type: application/json' );
echo json_encode( $data );
// Safe: handles edge cases, consistent output
wp_send_json_success( $data ); // uses wp_json_encode internallyWhen it matters most
- AJAX handlers returning post content or user input
- Localizing data with
wp_localize_script() - REST API custom endpoints
- Any site with multilingual content
Practical rule
Inside WordPress, always use wp_json_encode() over json_encode(). If you're using wp_send_json_success() or wp_send_json_error(), you're already covered - they call wp_json_encode() internally.
One small habit. Fewer silent bugs.
