您的位置:首页 > 编程语言 > PHP开发

无敌的跨站神器 PHP json_encode

2014-05-21 16:45 162 查看
文章太长,只转载核心部分,原文:无敌的跨站神器 PHP json_encode

可以跨域?那就无敌的,你懂的!!飞鸽传书 PHP 爱好者详细说明 json_encode 的使用。

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

json_encode — 对变量进行 JSON 编码

说明 ¶

string json_encode ( mixed $value [, int $options = 0 ] )

返回 value 值的 JSON 形式

参数 ¶

value

待编码的 value ,除了resource 类型之外,可以为任何数据类型

该函数只能接受 UTF-8 编码的数据

options

由以下常量组成的二进制掩码: JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_UNESCAPED_UNICODE.

返回值 ¶

编码成功则返回一个以 JSON 形式表示的 string 或者在失败时返回 FALSE 。

更新日志 ¶

版本

说明

5.4.0 options 参数增加常量: JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, 和 JSON_UNESCAPED_UNICODE。

5.3.3 options 参数增加常量:JSON_NUMERIC_CHECK。

5.3.0 增加 options 参数.

范例 ¶

Example #1 A json_encode() 的例子

<?php

$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);

echo json_encode($arr);

?>

以上例程会输出:

{"a":1,"b":2,"c":3,"d":4,"e":5}

Example #2 json_encode() 函数中 options 参数的用法

<?php

$a = array('<foo>',"'bar'",'"baz"','&blong&', "\xc3\xa9");

echo "Normal: ", json_encode($a), "\n";

echo "Tags: ", json_encode($a, JSON_HEX_TAG), "\n";

echo "Apos: ", json_encode($a, JSON_HEX_APOS), "\n";

echo "Quot: ", json_encode($a, JSON_HEX_QUOT), "\n";

echo "Amp: ", json_encode($a, JSON_HEX_AMP), "\n";

echo "Unicode: ", json_encode($a, JSON_UNESCAPED_UNICODE), "\n";

echo "All: ", json_encode($a, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE), "\n\n";

$b = array();

echo "Empty array output as array: ", json_encode($b), "\n";

echo "Empty array output as object: ", json_encode($b, JSON_FORCE_OBJECT), "\n\n";

$c = array(array(1,2,3));

echo "Non-associative array output as array: ", json_encode($c), "\n";

echo "Non-associative array output as object: ", json_encode($c, JSON_FORCE_OBJECT), "\n\n";

$d = array('foo' => 'bar', 'baz' => 'long');

echo "Associative array always output as object: ", json_encode($d), "\n";

echo "Associative array always output as object: ", json_encode($d, JSON_FORCE_OBJECT), "\n\n";

?>

以上例程会输出:

Normal: ["<foo>","'bar'","\"baz\"","&blong&","\u00e9"]

Tags: ["\u003Cfoo\u003E","'bar'","\"baz\"","&blong&","\u00e9"]

Apos: ["<foo>","\u0027bar\u0027","\"baz\"","&blong&","\u00e9"]

Quot: ["<foo>","'bar'","\u0022baz\u0022","&blong&","\u00e9"]

Amp: ["<foo>","'bar'","\"baz\"","\u0026blong\u0026","\u00e9"]

Unicode: ["<foo>","'bar'","\"baz\"","&blong&","é"]

All: ["\u003Cfoo\u003E","\u0027bar\u0027","\u0022baz\u0022","\u0026blong\u0026","é"]

Empty array output as array: []

Empty array output as object: {}

Non-associative array output as array: [[1,2,3]]

Non-associative array output as object: {"0":{"0":1,"1":2,"2":3}}

Associative array always output as object: {"foo":"bar","baz":"long"}

Associative array always output as object: {"foo":"bar","baz":"long"}

Example #3 连续与非连续数组示例

<?php

echo "连续数组".PHP_EOL;

$sequential = array("foo", "bar", "baz", "blong");

var_dump(

$sequential,

json_encode($sequential)

);

echo PHP_EOL."非连续数组".PHP_EOL;

$nonsequential = array(1=>"foo", 2=>"bar", 3=>"baz", 4=>"blong");

var_dump(

$nonsequential,

json_encode($nonsequential)

);

echo PHP_EOL."删除一个连续数组值的方式产生的非连续数组".PHP_EOL;

unset($sequential[1]);

var_dump(

$sequential,

json_encode($sequential)

);

?>

以上例程会输出:

连续数组

array(4) {

[0]=>

string(3) "foo"

[1]=>

string(3) "bar"

[2]=>

string(3) "baz"

[3]=>

string(5) "blong"

}

string(27) "["foo","bar","baz","blong"]"

非连续数组

array(4) {

[1]=>

string(3) "foo"

[2]=>

string(3) "bar"

[3]=>

string(3) "baz"

[4]=>

string(5) "blong"

}

string(43) "{"1":"foo","2":"bar","3":"baz","4":"blong"}"

删除一个连续数组值的方式产生的非连续数组

array(3) {

[0]=>

string(3) "foo"

[2]=>

string(3) "baz"

[3]=>

string(5) "blong"

}

string(33) "{"0":"foo","2":"baz","3":"blong"}"

注释 ¶

Note:

如果执行失败,可以通过 json_last_error() 函数来获取详细错误信息。

Note:

如果要编码的数组的键不是从0开始的数字,所有的键将会被当作字符串,并明确声明为 key-value 对。

参见 ¶

•JsonSerializable

•json_decode() - 对 JSON 格式的字符串进行编码

•json_last_error() - 返回最后发生的错误

add a note add a note

User Contributed Notes 66 notes

up

down

15

bohwaz ¶

2 years ago

Are you sure you want to use JSON_NUMERIC_CHECK, really really sure?

Just watch this usecase:

<?php

// International phone number

json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);

?>

And then you get this JSON:

{"phone_number":33123456789}

Maybe it makes sense for PHP (as is_numeric('+33123456789') returns true), but really, casting it as an int?!

So be careful when using JSON_NUMERIC_CHECK, it may mess up with your data!

up

down

13

bohwaz ¶

3 years ago

This is intended to be a simple readable json encode function for PHP 5.3+ (and licensed under GNU/AGPLv3 or GPLv3 like you prefer):

<?php

function json_readable_encode($in, $indent = 0, $from_array = false)

{

$_myself = __FUNCTION__;

$_escape = function ($str)

{

return preg_replace("!([\b\t\n\r\f\"\\'])!", "\\\\\\1", $str);

};

$out = '';

foreach ($in as $key=>$value)

{

$out .= str_repeat("\t", $indent + 1);

$out .= "\"".$_escape((string)$key)."\": ";

if (is_object($value) || is_array($value))

{

$out .= "\n";

$out .= $_myself($value, $indent + 1);

}

elseif (is_bool($value))

{

$out .= $value ? 'true' : 'false';

}

elseif (is_null($value))

{

$out .= 'null';

}

elseif (is_string($value))

{

$out .= "\"" . $_escape($value) ."\"";

}

else

{

$out .= $value;

}

$out .= ",\n";

}

if (!empty($out))

{

$out = substr($out, 0, -2);

}

$out = str_repeat("\t", $indent) . "{\n" . $out;

$out .= "\n" . str_repeat("\t", $indent) . "}";

return $out;

}

?>

up

down

9

andyrusterholz at g-m-a-i-l dot c-o-m ¶

5 years ago

For anyone who would like to encode arrays into JSON, but is using PHP 4, and doesn't want to wrangle PECL around, here is a function I wrote in PHP4 to convert nested arrays into JSON.

Note that, because javascript converts JSON data into either nested named objects OR vector arrays, it's quite difficult to represent mixed PHP arrays (arrays with both numerical and associative indexes) well in JSON. This function does something
funky if you pass it a mixed array -- see the comments for details.

I don't make a claim that this function is by any means complete (for example, it doesn't handle objects) so if you have any improvements, go for it.

<?php

/**

* Converts an associative array of arbitrary depth and dimension into JSON representation.

*

* NOTE: If you pass in a mixed associative and vector array, it will prefix each numerical

* key with "key_". For example array("foo", "bar" => "baz") will be translated into

* {"key_0": "foo", "bar": "baz"} but array("foo", "bar") would be translated into [ "foo", "bar" ].

*

* @param $array The array to convert.

* @return mixed The resulting JSON string, or false if the argument was not an array.

* @author Andy Rusterholz

*/

function array_to_json( $array ){

if( !is_array( $array ) ){

return false;

}

$associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) ));

if( $associative ){

$construct = array();

foreach( $array as $key => $value ){

// We first copy each key/value pair into a staging array,

// formatting each key and value properly as we go.

// Format the key:

if( is_numeric($key) ){

$key = "key_$key";

}

$key = '"'.addslashes($key).'"';

// Format the value:

if( is_array( $value )){

$value = array_to_json( $value );

} else if( !is_numeric( $value ) || is_string( $value ) ){

$value = '"'.addslashes($value).'"';

}

// Add to staging array:

$construct[] = "$key: $value";

}

// Then we collapse the staging array into the JSON form:

$result = "{ " . implode( ", ", $construct ) . " }";

} else { // If the array is a vector (not associative):

$construct = array();

foreach( $array as $value ){

// Format the value:

if( is_array( $value )){

$value = array_to_json( $value );

} else if( !is_numeric( $value ) || is_string( $value ) ){

$value = '"'.addslashes($value).'"';

}

// Add to staging array:

$construct[] = $value;

}

// Then we collapse the staging array into the JSON form:

$result = "[ " . implode( ", ", $construct ) . " ]";

}

return $result;

}

?>

up

down

8

migprj at gmail dot com ¶

3 years ago

Because json_encode() only deals with utf8, it is often necessary to convert all the string values inside an array to utf8. I've created these two functions:

<?php

function utf8_encode_all($dat) // -- It returns $dat encoded to UTF8

{

if (is_string($dat)) return utf8_encode($dat);

if (!is_array($dat)) return $dat;

$ret = array();

foreach($dat as $i=>$d) $ret[$i] = utf8_encode_all($d);

return $ret;

}

/* ....... */

function utf8_decode_all($dat) // -- It returns $dat decoded from UTF8

{

if (is_string($dat)) return utf8_decode($dat);

if (!is_array($dat)) return $dat;

$ret = array();

foreach($dat as $i=>$d) $ret[$i] = utf8_decode_all($d);

return $ret;

}

/* ....... */

?>

up

down

10

Sam Barnum ¶

5 years ago

Note that if you try to encode an array containing non-utf values, you'll get null values in the resulting JSON string. You can batch-encode all the elements of an array with the array_map function:

<?php

$encodedArray = array_map(utf8_encode, $rawArray);

?>

up

down

9

guilhenfsu at gmail dot com ¶

1 year ago

Solution for UTF-8 Special Chars.

<?

$array = array('nome'=>'Paição','cidade'=>'São Paulo');

$array = array_map('htmlentities',$array);

//encode

$json = html_entity_decode(json_encode($array));

//Output: {"nome":"

aição","cidade":"São Paulo"}

echo $json;

?>

up

down

4

ryan at ryanparman dot com ¶

4 years ago

I came across the "bug" where running json_encode() over a SimpleXML object was ignoring the CDATA. I ran acrosshttp://bugs.php.net/42001 and http://bugs.php.net/41976,
and while I agree with the poster that the documentation should clarify gotchas like this, I was able to figure out how to workaround it.

You need to convert the SimpleXML object back into an XML string, then re-import it back into SimpleXML using the LIBXML_NOCDATA option. Once you do this, then you can use json_encode() and still get back the CDATA.

<?php

// Pretend we already have a complex SimpleXML object stored in $xml

$json = json_encode(new SimpleXMLElement($xml->asXML(), LIBXML_NOCDATA));

?>

up

down

6

devilan (REMOVEIT) (at) o2 (dot) pl ¶

2 years ago

For PHP5.3 users who want to emulate JSON_UNESCAPED_UNICODE, there is simple way to do it:

<?php

function my_json_encode($arr)

{

//convmap since 0x80 char codes so it takes all multibyte codes (above ASCII 127). So such characters are being "hidden" from normal json_encoding

array_walk_recursive($arr, function (&$item, $key) { if (is_string($item)) $item = mb_encode_numericentity($item, array (0x80, 0xffff, 0, 0xffff), 'UTF-8'); });

return mb_decode_numericentity(json_encode($arr), array (0x80, 0xffff, 0, 0xffff), 'UTF-8');

}

?>

up

down

3

Garrett ¶

5 years ago

A note about json_encode automatically quoting numbers:

It appears that the json_encode function pays attention to the data type of the value. Let me explain what we came across:

We have found that when retrieving data from our database, there are occasions when numbers appear as strings to json_encode which results in double quotes around the values.

This can lead to problems within javascript functions expecting the values to be numeric.

This was discovered when were were retrieving fields from the database which contained serialized arrays. After unserializing them and sending them through the json_encode function the numeric values in the original array were now being treated
as strings and showing up with double quotes around them.

The fix: Prior to encoding the array, send it to a function which checks for numeric types and casts accordingly. Encoding from then on worked as expected.

up

down

4

drdamour ¶

7 months ago

note that although PHP bundles JSON, some linux distributions do not do to a licensing conflict. As such you may need to install json support yourself.

IE: on Ubuntu 13.10 Saucy Salamander apt-get install php5-json re-enables json support (json_encode and json_decode)

up

down

4

CertaiN ¶

10 months ago

<?php

$fp = fopen('php://stdin', 'r');

$json = @json_encode(array('a' => 'foo', 'b' => $fp));

var_dump($json);

?>

[PHP5.5 or after]

bool(false)

[PHP 5.4 or before]

string(20) "{"a":"foo","b":null}"

up

down

4

dan at elearnapp dot com ¶

3 years ago

If you need to force an object (ex: empty array) you can also do:

<?php json_encode( (object)$arr ); ?>

which acts the same as

<?php json_encode($arr, JSON_FORCE_OBJECT); ?>

up

down

3

mmi at uhb-consulting dot de ¶

2 years ago

When you have trouble with json_encode and German umlauts. json_encode converts Strings to NULL when detecting umlauts not being UTF8encoded.

Here's another recursive UTF8 conversion function and vice-versa. The object handling might be buggy but works for me.

<?php

function array_utf8_encode_recursive($dat)

{ if (is_string($dat)) {

return utf8_encode($dat);

}

if (is_object($dat)) {

$ovs= get_object_vars($dat);

$new=$dat;

foreach ($ovs as $k =>$v) {

$new->$k=array_utf8_encode_recursive($new->$k);

}

return $new;

}

if (!is_array($dat)) return $dat;

$ret = array();

foreach($dat as $i=>$d) $ret[$i] = array_utf8_encode_recursive($d);

return $ret;

}

function array_utf8_decode_recursive($dat)

{ if (is_string($dat)) {

return utf8_decode($dat);

}

if (is_object($dat)) {

$ovs= get_object_vars($dat);

$new=$dat;

foreach ($ovs as $k =>$v) {

$new->$k=array_utf8_decode_recursive($new->$k);

}

return $new;

}

if (!is_array($dat)) return $dat;

$ret = array();

foreach($dat as $i=>$d) $ret[$i] = array_utf8_decode_recursive($d);

return $ret;

}

?>

up

down

3

Dave - s10sys.com ¶

3 years ago

This may help others who are seeing null strings returned by json_encode().

This function will encode all array values to utf8 so they are safe for json_encode();

usage:

<?php

json_encode(utf8json($dataArray));

function utf8json($inArray) {

static $depth = 0;

/* our return object */

$newArray = array();

/* safety recursion limit */

$depth ++;

if($depth >= '30') {

return false;

}

/* step through inArray */

foreach($inArray as $key=>$val) {

if(is_array($val)) {

/* recurse on array elements */

$newArray[$key] = utf8json($val);

} else {

/* encode string values */

$newArray[$key] = utf8_encode($val);

}

}

/* return utf8 encoded array */

return $newArray;

}

?>

[NOTE BY danbrown AT php DOT net: Includes a bugfix by (robbiz233 AT hotmail DOT com) on 18-SEP-2010, to replace:

$newArray[$key] = utf8json($inArray);

with:

$newArray[$key] = utf8json($val);"

in the given function.]

up

down

3

Istratov Vadim ¶

4 years ago

Be careful with floating values in some locales (e.g. russian) with comma (",") as decimal point. Code:

<?php

setlocale(LC_ALL, 'ru_RU.utf8');

$arr = array('element' => 12.34);

echo json_encode( $arr );

?>

Output will be:

--------------

{"element":12,34}

--------------

Which is NOT a valid JSON markup. You should convert floating point variable to strings or set locale to something like "LC_NUMERIC, 'en_US.utf8'" before using json_encode.

up

down

3

spam.goes.in.here AT gmail.com ¶

5 years ago

For anyone who has run into the problem of private properties not being added, you can simply implement the IteratorAggregate interface with the getIterator() method. Add the properties you want to be included in the output into an array in the
getIterator() method and return it.

up

down

2

matt dot parlane at gmail dot com ¶

3 years ago


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: