JSON 函数
在线手册:中文  英文

json_decode

(PHP 5 >= 5.2.0, PECL json >= 1.2.0)

json_decode对 JSON 格式的字符串进行编码

说明

mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

接受一个 JSON 格式的字符串并且把它转换为 PHP 变量

参数

json

待解码的 json string 格式的字符串。

This function only works with UTF-8 encoded data.

assoc

当该参数为 TRUE 时,将返回 array 而非 object

depth

User specified recursion depth.

options

Bitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats)

返回值

Returns the value encoded in json in appropriate PHP type. Values true, false and null (case-insensitive) are returned as TRUE, FALSE and NULL respectively. NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.

范例

Example #1 json_decode() 的例子

<?php
$json 
'{"a":1,"b":2,"c":3,"d":4,"e":5}';

var_dump(json_decode($json));
var_dump(json_decode($jsontrue));

?>

以上例程会输出:

object(stdClass)#1 (5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}

Example #2 Accessing invalid object properties

Accessing elements within an object that contain characters not permitted under PHP's naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe.

<?php

$json 
'{"foo-bar": 12345}';

$obj json_decode($json);
print 
$obj->{'foo-bar'}; // 12345

?>

Example #3 common mistakes using json_decode()

<?php

// the following strings are valid JavaScript but not valid JSON

// the name and value must be enclosed in double quotes
// single quotes are not valid 
$bad_json "{ 'bar': 'baz' }";
json_decode($bad_json); // null

// the name must be enclosed in double quotes
$bad_json '{ bar: "baz" }';
json_decode($bad_json); // null

// trailing commas are not allowed
$bad_json '{ bar: "baz", }';
json_decode($bad_json); // null

?>

Example #4 depth errors

<?php
// Encode the data.
$json json_encode(
    array(
        
=> array(
            
'English' => array(
                
'One',
                
'January'
            
),
            
'French' => array(
                
'Une',
                
'Janvier'
            
)
        )
    )
);

// Define the errors.
$constants get_defined_constants(true);
$json_errors = array();
foreach (
$constants["json"] as $name => $value) {
    if (!
strncmp($name"JSON_ERROR_"11)) {
        
$json_errors[$value] = $name;
    }
}

// Show the errors for different depths.
foreach (range(43, -1) as $depth) {
    
var_dump(json_decode($jsontrue$depth));
    echo 
'Last error: '$json_errors[json_last_error()], PHP_EOLPHP_EOL;
}
?>

以上例程会输出:

array(1) {
  [1]=>
  array(2) {
    ["English"]=>
    array(2) {
      [0]=>
      string(3) "One"
      [1]=>
      string(7) "January"
    }
    ["French"]=>
    array(2) {
      [0]=>
      string(3) "Une"
      [1]=>
      string(7) "Janvier"
    }
  }
}
Last error: JSON_ERROR_NONE

NULL
Last error: JSON_ERROR_DEPTH

Example #5 json_decode() of large integers

<?php
$json 
'12345678901234567890';

var_dump(json_decode($json));
var_dump(json_decode($jsonfalse512JSON_BIGINT_AS_STRING));

?>

以上例程会输出:

float(1.2345678901235E+19)
string(20) "12345678901234567890"

注释

Note:

The JSON spec is not JavaScript, but a subset of JavaScript.

Note:

In the event of a failure to decode, json_last_error() can be used to determine the exact nature of the error.

更新日志

版本 说明
5.4.0 The options parameter was added.
5.3.0 Added the optional depth. The default recursion depth was increased from 128 to 512
5.2.3 The nesting limit was increased from 20 to 128
5.2.1 Added support for JSON decoding of basic types.

参见


JSON 函数
在线手册:中文  英文

用户评论:

php_net_01_weber at nachvorne de (2013-04-30 23:18:08)

json_decode_nice + keep linebreaks:
function json_decode_nice($json, $assoc = TRUE){
$json = str_replace(array("\n","\r"),"\\n",$json);
$json = preg_replace('/([{,]+)(\s*)([^"]+?)\s*:/','$1"$3":',$json);
$json = preg_replace('/(,)\s*}$/','}',$json);
return json_decode($json,$assoc);
}
by phpdoc at badassawesome dot com, I just changed line 2.
If you want to keep the linebreaks just escape the slash.

phpdoc at badassawesome dot com (2013-04-12 21:39:26)

I added a 3rd regex to the json_decode_nice function by "colin.mollenhour.com" to handle a trailing comma in json definition.

<?php
// http://www.php.net/manual/en/function.json-decode.php#95782
function json_decode_nice($json$assoc FALSE){ 
    
$json str_replace(array("\n","\r"),"",$json); 
    
$json preg_replace('/([{,]+)(\s*)([^"]+?)\s*:/','$1"$3":',$json);
    
$json preg_replace('/(,)\s*}$/','}',$json);
    return 
json_decode($json,$assoc); 
}
?>

Example:

<?php
$dat_json 
= <<<EOF
{
    "foo"    : "bam",
    "bar"    : "baz",
}
EOF;
$dat_array json_decode_nice$dat_json );
var_dump $dat_json$dat_array ); 

/* RESULTS:

string(35) "{
    "foo"    : "bam",
    "bar"    : "baz",
}"
array(2) {
  ["foo"]=>
  string(3) "bam"
  ["bar"]=>
  string(3) "baz"
}
*/
?>

1franck (2013-03-03 16:47:38)

Sometime, i need to allow comments in json file. So i wrote a small func to clean comments in a json string before decoding it:
<?php
/**
 * Clean comments of json content and decode it with json_decode().
 * Work like the original php json_decode() function with the same params
 *
 * @param   string  $json    The json string being decoded
 * @param   bool    $assoc   When TRUE, returned objects will be converted into associative arrays. 
 * @param   integer $depth   User specified recursion depth. (>=5.3)
 * @param   integer $options Bitmask of JSON decode options. (>=5.4)
 * @return  string
 */
function json_clean_decode($json$assoc false$depth 512$options 0) {

    
// search and remove comments like /* */ and //
    
$json preg_replace("#(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|([\s\t](//).*)#"''$json);

    if(
version_compare(phpversion(), '5.4.0''>=')) { 
        
$json json_decode($json$assoc$depth$options);
    }
    elseif(
version_compare(phpversion(), '5.3.0''>=')) { 
        
$json json_decode($json$assoc$depth);
    }
    else {
        
$json json_decode($json$assoc);
    }

    return 
$json;
}
?>

skypppher at gmail dot com (2012-12-11 19:40:04)

First of all, since JSON is not native PHP format or even native JavaScript format, everyone who wants to use JSON wisely should carefuly read official documentation. There is a link to it here, in "Introduction" section. Many questions like "it doesn't recognize my strings" and those like previous one (about zip codes) will drop if you will be attentive!

And second. I've found that there is no good, real working example of how to validate string if it is a JSON or not.
There are two ways to make this: parse input string for yourself using regular expressions or anything else, use json_decode to do it for you.
Parsing for yourself is like writing your own compiler, too difficult.
Just testing result of json_decode is not enough because you should test it with NULL, but valid JSON could be like this 'null' and it will evaluate to NULL. So you should use another function - json_last_error. It will return error code of the last encode/decode operation. If no error occured it will be JSON_ERROR_NONE. So here is the function you should use for testing:
<?php
function isValidJson($strJson) {
    
json_decode($strJson);
    return (
json_last_error() === JSON_ERROR_NONE);
}
?>
It's so simple, that there is no need to use it and slow down your script with extra delay for function call. Just do it manualy in you code while working with input data:
<?php
//here is my initial string
$sJson $_POST['json'];
//try to decode it
$json json_decode($sJson);
if (
json_last_error() === JSON_ERROR_NONE) {
    
//do something with $json. It's ready to use
} else {
    
//yep, it's not JSON. Log error or alert someone or do nothing
}
?>

alexvonweiss at googlemail dot com (2011-09-23 08:49:11)

Consider that JSON can differ between int and string. So

<?php
var_dump
(json_decode('{"foo": 12}'));
// array(1) { ["foo"]=> int(12) }

var_dump(json_decode('{"foo": "12"}'));
// array(1) { ["foo"]=> string(12) }
?>

Numbers that cannot be handled by integer seems to become float casted. This can be a problem if you transfer big numbers like facebook ids over JSON. Either you avoid numbers by cast everything to string before JSON.stringify or you have to use number_format if the value bacome a float value.

<?php
// test
$x json_decode('{"foo": 123456789012345}');
echo 
sprintf('%1$f'$x->foo).PHP_EOL;
echo 
sprintf('%1$u'$x->foo).PHP_EOL;
echo 
sprintf('%1$s'$x->foo).PHP_EOL;
echo 
strval($x->foo).PHP_EOL;
echo (string) 
$x->foo.PHP_EOL;
echo 
number_format($x->foo0'''').PHP_EOL;

// output
123456789012345.000000  // printf %f
2249056121              // printf %u
1.2345678901234E+14     // printf %s
1.2345678901234E+14     // strval()
1.2345678901234E+14     // cast (string)
2249056121              // cast (int)
123456789012345         // number_format()
?>

evengard at trioptimum dot com (2011-04-13 08:58:34)

There is a problem when passing to json_decode a string with the "\" symbol. It seems to identify it as an escape character and trying to follow it. So sometimes it leads to failed parsing.

It seems that just replacing it with "\\" helps.
<?php
print_r
(json_decode(str_replace('\\''\\\\''{"name":"/\"}')));
?>
where /\ is the string which doesn't worked.

T erkif (2010-08-10 15:03:17)

it seems, that some of the people are not aware, that if you are using json_decode to decode a string it HAS to be a propper json string:

<?php
var_dump
(json_encode('Hello'));

var_dump(json_decode('Hello'));  // wrong
var_dump(json_decode("Hello")); // wrong
var_dump(json_decode('"Hello"')); // correct
var_dump(json_decode("'Hello'")); // wrong

result:

string(7""Hello""
NULL
NULL
string
(5"Hello"
NULL

majca J (2010-06-05 17:42:08)

Noted in a comment below is that this function will return NULL when given a simple string.
This is new behavior - see the result in PHP 5.2.4 :
php > var_dump(json_decode('this is a simple string'));
string(23) "this is a simple string"
in PHP 5.3.2 :
php > var_dump(json_decode('this is a simple string'));
NULL
I had several functions that relied on checking the value of a purported JSON string if it didn't decode into an object/array. If you do too, be sure to be aware of this when upgrading to PHP 5.3.

php at hm2k.org (2010-02-11 16:45:34)

If var_dump produces NULL, you may be experiencing JSONP aka JSON with padding, here's a quick fix...

<?php

//remove padding
$body=preg_replace('/.+?({.+}).+/','$1',$body);

// now, process the JSON string
$result json_decode($body);

var_dump($result);
?>

nix (2010-01-29 03:39:05)

Be aware, when decoding JSON strings, where an empty string is a key, this library replaces the empty string with "_empty_".

So the following code gives an unexpected result:
<?php
var_dump
(json_decode('{"":"arbitrary"}'));
?>

The result is as follows:
object(stdClass)#1 (1) {
  ["_empty_"]=>
  string(6) "arbitrary"
}

Any subsequent key named "_empty_" (or "" [the empty string] again) will overwrite the value.

colin.mollenhour.com (2010-01-21 10:51:32)

For those of you wanting json_decode to be a little more lenient (more like Javascript), here is a wrapper:

<?php
function json_decode_nice($json$assoc FALSE){
    
$json str_replace(array("\n","\r"),"",$json);
    
$json preg_replace('/([{,]+)(\s*)([^"]+?)\s*:/','$1"$3":',$json);
    return 
json_decode($json,$assoc);
}
?>

Some examples of accepted syntax:

<?php
$json 
'{a:{b:"c",d:["e","f",0]}}';
$json 
'{
   a : {
      b : "c",
      "d.e.f": "g"
   }
}'
;
?>

If your content needs to have newlines, do this:

<?php
$string 
"This
Text
Has
Newlines"
;
$json '{withnewlines:'.json_encode($string).'}';
?>

Note: This does not fix trailing commas or single quotes.

[EDIT BY danbrown AT php DOT net: Contains a bugfix provided by (sskaje AT gmail DOT com) on 05-DEC-2012 with the following note.]

Old regexp failed when json like
{aaa:[{a:1},{a:2}]}

premiersullivan at gmail dot com (2009-06-21 16:14:41)

This function will remove trailing commas and encode in utf8, which might solve many people's problems. Someone might want to expand it to also change single quotes to double quotes, and fix other kinds of json breakage.

<?php
    
function mjson_decode($json)
    {
        return 
json_decode(removeTrailingCommas(utf8_encode($json)));
    }
    
    function 
removeTrailingCommas($json)
    {
        
$json=preg_replace('/,\s*([\]}])/m''$1'$json);
        return 
$json;
    }
?>

Gravis (2009-05-09 19:38:44)

with two lines you can convert your string from JavaScript toSource() (see http://www.w3schools.com/jsref/jsref_toSource.asp) output format to JSON accepted format.  this works with subobjects too!
note: toSource() is part of JavaScript 1.3 but only implemented in Mozilla based javascript engines (not Opera/IE/Safari/Chrome).

<?php
  $str 
'({strvar:"string", number:40, boolvar:true, subobject:{substrvar:"sub string", subsubobj:{deep:"deeply nested"}, strnum:"56"}, false_val:false, false_str:"false"})'// example javascript object toSource() output

  
$str substr($str1strlen($str) - 2); // remove outer ( and )
  
$str preg_replace("/([a-zA-Z0-9_]+?):/" "\"$1\":"$str); // fix variable names

  
$output json_decode($strtrue);
  
var_dump($output);
?> 

var_dump output:
array(6) {
  ["strvar"]=>
  string(6) "string"
  ["number"]=>
  int(40)
  ["boolvar"]=>
  bool(true)
  ["subobject"]=>
  array(3) {
    ["substrvar"]=>
    string(10) "sub string"
    ["subsubobj"]=>
    array(1) {
      ["deep"]=>
      string(13) "deeply nested"
    }
    ["strnum"]=>
    string(2) "56"
  }
  ["false_val"]=>
  bool(false)
  ["false_str"]=>
  string(5) "false"
}

hope this saves someone some time.

Aaron Kardell (2008-11-13 19:39:02)

Make sure you pass in utf8 content, or json_decode may error out and just return a null value.  For a particular web service I was using, I had to do the following:

<?php
$contents 
file_get_contents($url);
$contents utf8_encode($contents);
$results json_decode($contents);
?>

Hope this helps!

steven at acko dot net (2008-10-07 00:49:55)

json_decode()'s handling of invalid JSON is very flaky, and it is very hard to reliably determine if the decoding succeeded or not. Observe the following examples, none of which contain valid JSON:

The following each returns NULL, as you might expect:

<?php
var_dump
(json_decode('['));             // unmatched bracket
var_dump(json_decode('{'));             // unmatched brace
var_dump(json_decode('{}}'));           // unmatched brace
var_dump(json_decode('{error error}')); // invalid object key/value
notation
var_dump
(json_decode('["\"]'));         // unclosed string
var_dump(json_decode('[" \x "]'));      // invalid escape code

Yet the following each returns the literal string you passed to it:

var_dump(json_decode(' [')); // unmatched bracket
var_dump(json_decode(' {')); // unmatched brace
var_dump(json_decode(' {}}')); // unmatched brace
var_dump(json_decode(' {error error}')); // invalid object key/value notation
var_dump(json_decode('"\"')); // unclosed string
var_dump(json_decode('" \x "')); // invalid escape code
?>

(this is on PHP 5.2.6)

Reported as a bug, but oddly enough, it was closed as not a bug.

[NOTE BY danbrown AT php DOT net: This was later re-evaluated and it was determined that an issue did in fact exist, and was patched by members of the Development Team.  See http://bugs.php.net/bug.php?id=45989 for details.]

jrevillini (2008-09-26 12:01:44)

When decoding strings from the database, make sure the input was encoded with the correct charset when it was input to the database.
I was using a form to create records in the DB which had a content field that was valid JSON, but it included curly apostrophes. If the page with the form did not have
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
in the head, then the data was sent to the database with the wrong encoding. Then, when json_decode tried to convert the string to an object, it failed every time.

nospam (AT) hjcms (DOT) de (2007-04-22 09:15:52)

You can't transport Objects or serialize Classes, json_* replace it bei stdClass!
<?php

$dom 
= new DomDocument'1.0''utf-8' );
$body $dom->appendChild$dom->createElement"body" ) );
$body->appendChild$dom->createElement"forward""Hallo" ) );

$JSON_STRING json_encode(
   array(
      
"aArray" => range"a""z" ),
      
"bArray" => range150 ),
      
"cArray" => range150),
      
"String" => "Value",
      
"stdClass" => $dom,
      
"XML" => $dom->saveXML()
   )
);

unset( 
$dom );

$Search "XML";
$MyStdClass json_decode$JSON_STRING );
// var_dump( "<pre>" , $MyStdClass , "</pre>" );

try {

   throw new 
Exception"$Search isn't a Instance of 'stdClass' Class by json_decode()." );

   if ( 
$MyStdClass->$Search instanceof $MyStdClass )
      
var_dump"<pre>instanceof:" $MyStdClass->$Search "</pre>" );

} catch( 
Exception $ErrorHandle ) {

   echo 
$ErrorHandle->getMessage();

   if ( 
property_exists$MyStdClass$Search ) ) {
      
$dom = new DomDocument"1.0""utf-8" );
      
$dom->loadXML$MyStdClass->$Search );
      
$body $dom->getElementsByTagName"body" )->item(0);
      
$body->appendChild$dom->createElement"rewind""Nice" ) );
      
var_dumphtmlentities$dom->saveXML(), ENT_QUOTES'utf-8' ) );
   }
}

?>

易百教程