#30471 closed defect (bug) (fixed)
json_encode() fails on non-utf8 strings
Reported by: | pento | Owned by: | pento |
---|---|---|---|
Milestone: | 4.1 | Priority: | normal |
Severity: | normal | Version: | 4.1 |
Component: | General | Keywords: | has-patch |
Focuses: | Cc: |
Description
In PHP 5.4 and earlier, when json_encode()
is run on a string that contains non-UTF-8 characters, it will return the string 'null'
. As of PHP 5.5, the string will be converted to UTF-8 before it's escaped for the JSON output.
Given this example:
$charsets = mb_detect_order(); if ( ! in_array( 'EUC-JP', $charsets ) ) { $charsets[] = 'EUC-JP'; mb_detect_order( $charsets ); } $eucjp = mb_convert_encoding( 'aあb', 'EUC-JP', 'UTF-8' ); $utf8 = mb_convert_encoding( $eucjp, 'UTF-8', 'EUC-JP' ); $json = wp_json_encode( $eucjp );
$json
will be the string 'null'
in PHP 5.4 an older, and the string "a\u3042b"'
in PHP 5.5+.
This becomes more complex as we try to encode arrays or objects.
$json = wp_json_encode( array( 'c', $eucjp ) );
Here, $json
will be the string '["c",null]'
in PHP 5.4 an older, and the string '["c","a\u3042b"]'
in PHP 5.5+.
It's fairly simple to fix this in wp_json_encode()
for strings, and horrible to try and fix it for arbitrary arrays/objects.
Attachments (2)
Change History (8)
#2
@
10 years ago
- Keywords has-patch added
30471.diff fixes this for plain strings.
Walking through arbitrary arrays/objects to check for non UTF-8 characters isn't a good option.
Maybe we could do a lazy check for $json
containing the string null
, and version_compare( PHP_VERSION, '5.4', '<=' )
? This will give false positives when $data
contains an array or object with a null
value, but it's a lot faster than an element-by-element check.
#3
@
10 years ago
30471.2.diff will run whenever PHP < 5.5, and $json
contains the string null
.
Also, in case we decide to go with 30471.diff, it contains a bug - it returns null
instead of 'null'
.
#4
@
10 years ago
- Owner set to pento
- Resolution set to fixed
- Status changed from new to closed
In 30561:
In 30534: