PHP Conference Japan 2024

json_encode

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

json_encode返回值的 JSON 表示形式

描述

json_encode(混合 $value, 整数 $flags = 0, 整数 $depth = 512): 字符串|false

返回一个包含提供的 value 的 JSON 表示形式的字符串。如果参数是 数组对象,它将被递归序列化。

如果要序列化的值是一个对象,则默认情况下只包含公开可见的属性。或者,一个类可以实现 JsonSerializable 来控制其值如何序列化为 JSON

编码受提供的 flags 影响,此外浮点值的编码取决于 serialize_precision 的值。

参数

value

正在编码的 value。可以是除 资源 之外的任何类型。

所有字符串数据必须使用 UTF-8 编码。

注意:

PHP 实现了一个 JSON 的超集,如原始的 » RFC 7159 中所指定。

flags

JSON_FORCE_OBJECTJSON_HEX_QUOTJSON_HEX_TAGJSON_HEX_AMPJSON_HEX_APOSJSON_INVALID_UTF8_IGNOREJSON_INVALID_UTF8_SUBSTITUTEJSON_NUMERIC_CHECKJSON_PARTIAL_OUTPUT_ON_ERRORJSON_PRESERVE_ZERO_FRACTIONJSON_PRETTY_PRINTJSON_UNESCAPED_LINE_TERMINATORSJSON_UNESCAPED_SLASHESJSON_UNESCAPED_UNICODEJSON_THROW_ON_ERROR 组成的位掩码。这些常量的行为在 JSON 常量 页面上进行了描述。

depth

设置最大深度。必须大于零。

返回值

成功时返回一个 JSON 编码的 字符串,失败时返回 false

变更日志

版本 描述
7.3.0 添加了 JSON_THROW_ON_ERROR flags
7.2.0 添加了 JSON_INVALID_UTF8_IGNOREJSON_INVALID_UTF8_SUBSTITUTE flags
7.1.0 添加了 JSON_UNESCAPED_LINE_TERMINATORS flags
7.1.0 编码 浮点数 值时,使用 serialize_precision 而不是 precision

示例

示例 #1 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}

示例 #2 显示一些标志使用的 json_encode() 示例

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

echo
"正常输出: ", json_encode($a), "\n";
echo
"标签转十六进制: ", json_encode($a, JSON_HEX_TAG), "\n";
echo
"单引号转十六进制: ", json_encode($a, JSON_HEX_APOS), "\n";
echo
"双引号转十六进制: ", json_encode($a, JSON_HEX_QUOT), "\n";
echo
"&转十六进制: ", json_encode($a, JSON_HEX_AMP), "\n";
echo
"Unicode编码: ", json_encode($a, JSON_UNESCAPED_UNICODE), "\n";
echo
"所有特殊字符转十六进制: ", json_encode($a, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE), "\n\n";

$b = array();

echo
"空数组输出为数组: ", json_encode($b), "\n";
echo
"空数组输出为对象: ", json_encode($b, JSON_FORCE_OBJECT), "\n\n";

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

echo
"非关联数组输出为数组: ", json_encode($c), "\n";
echo
"非关联数组输出为对象: ", json_encode($c, JSON_FORCE_OBJECT), "\n\n";

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

echo
"关联数组始终输出为对象: ", json_encode($d), "\n";
echo
"关联数组始终输出为对象: ", 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"}

示例 #3 JSON_NUMERIC_CHECK 选项示例

<?php
echo "表示数字的字符串将自动转换为数字".PHP_EOL;
$numbers = array('+123123', '-123123', '1.2e3', '0.00001');
var_dump(
$numbers,
json_encode($numbers, JSON_NUMERIC_CHECK)
);
echo
"包含格式错误的数字的字符串".PHP_EOL;
$strings = array('+a33123456789', 'a123');
var_dump(
$strings,
json_encode($strings, JSON_NUMERIC_CHECK)
);
?>

以上示例将输出类似以下内容

Strings representing numbers automatically turned into numbers
array(4) {
  [0]=>
  string(7) "+123123"
  [1]=>
  string(7) "-123123"
  [2]=>
  string(5) "1.2e3"
  [3]=>
  string(7) "0.00001"
}
string(28) "[123123,-123123,1200,1.0e-5]"
Strings containing improperly formatted numbers
array(2) {
  [0]=>
  string(13) "+a33123456789"
  [1]=>
  string(4) "a123"
}
string(24) "["+a33123456789","a123"]"

示例 #4 顺序与非顺序数组示例

<?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."顺序数组,其中一个键被 unset".PHP_EOL;
unset(
$sequential[1]);
var_dump(
$sequential,
json_encode($sequential)
);
?>

以上示例将输出

Sequential array
array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(3) "baz"
  [3]=>
  string(5) "blong"
}
string(27) "["foo","bar","baz","blong"]"

Non-sequential array
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"}"

Sequential array with one key unset
array(3) {
  [0]=>
  string(3) "foo"
  [2]=>
  string(3) "baz"
  [3]=>
  string(5) "blong"
}
string(33) "{"0":"foo","2":"baz","3":"blong"}"

示例 #5 JSON_PRESERVE_ZERO_FRACTION 选项示例

<?php
var_dump
(json_encode(12.0, JSON_PRESERVE_ZERO_FRACTION));
var_dump(json_encode(12.0));
?>

以上示例将输出

string(4) "12.0"
string(2) "12"

注释

注意:

如果编码失败,可以使用 json_last_error() 来确定错误的确切性质。

注意:

在编码数组时,如果键不是从 0 开始的连续数字序列,则所有键都将编码为字符串,并为每个键值对显式指定。

注意:

与参考 JSON 编码器一样,json_encode() 如果给定一个 字符串整数浮点数布尔值 作为输入 ,则会生成一个简单值(即既不是对象也不是数组)的 JSON。虽然大多数解码器会接受这些值作为有效的 JSON,但有些可能不会,因为规范在这方面模棱两可。

总而言之,始终测试您的 JSON 解码器是否能够处理您从 json_encode() 生成的输出。

参见

添加注释

用户贡献的注释 11 条注释

108
bohwaz
13 年前
您确定要使用 JSON_NUMERIC_CHECK 吗,真的真的确定吗?

请看这个用例

<?php
// 国际电话号码
json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);
?>

然后您将得到此 JSON

{"phone_number":33123456789}

也许这对 PHP 来说是有意义的(因为 is_numeric('+33123456789') 返回 true),但实际上,将其转换为整数?!

因此在使用 JSON_NUMERIC_CHECK 时要小心,它可能会弄乱您的数据!
8
elliseproduction at gmail dot com
2 年前
请注意,JSON_FORCE_OBJECT 会将所有非关联数组转换为对象。对于空数组来说,这并非总是好的解决方案。
如果您只想将空数组转换为对象,只需在使用 json_encode 函数之前将其转换为空对象。

例如

<?php

$foo
=array(
'empty2object'=>(object)[],
'empty2array'=>[],
);

echo
json_encode($foo); // {"empty2object":{},"empty2array":[]}

?>
7
ck at ergovia dot de
11年前
在将普通数组传递给 json_encode 并使用 JSON_FORCE_OBJECT 时需要注意。我发现生成的 JSON 字符串的索引顺序取决于 PHP 运行的系统。

$a = array("a" , "b", "c");
echo json_encode($a, JSON_FORCE_OBJECT);

在 Xampp(Windows)上,您将得到

{"0":"a","1":"b","2":"c"}';

在运行 Debian 的机器上,我得到

{"2":"a","1":"b","0":"c"}';

请注意,键值对是不同的!

这里的解决方案是使用 array_combine 创建关联数组,然后将其传递给 json_encode

json_encode(array_combine(range(0, count($a) - 1), $a), JSON_FORCE_OBJECT);
7
Istratov Vadim
15年前
在某些地区(例如俄语)中使用逗号(“,”)作为小数点时,请小心处理浮点值。代码

<?php
setlocale
(LC_ALL, 'ru_RU.utf8');

$arr = array('element' => 12.34);
echo
json_encode( $arr );
?>

输出将是
--------------
{"element":12,34}
--------------

这不是有效的 JSON 标记。在使用 json_encode 之前,您应该将浮点变量转换为字符串或将区域设置设置为类似“LC_NUMERIC, 'en_US.utf8'”的内容。
5
ryan at ryanparman dot com
14年前
我遇到了在 SimpleXML 对象上运行 json_encode() 会忽略 CDATA 的“错误”。我遇到了http://bugs.php.net/42001http://bugs.php.net/41976, 虽然我同意发布者认为文档应该阐明此类问题,但我能够弄清楚如何解决它。

您需要将 SimpleXML 对象转换回 XML 字符串,然后使用 LIBXML_NOCDATA 选项将其重新导入回 SimpleXML。完成此操作后,您可以使用 json_encode() 并仍然获取回 CDATA。

<?php
// 假设我们已经有一个存储在 $xml 中的复杂 SimpleXML 对象
$json = json_encode(new SimpleXMLElement($xml->asXML(), LIBXML_NOCDATA));
?>
3
Garrett
16年前
关于 json_encode 自动引用数字的说明

json_encode 函数似乎会关注值的类型。让我解释一下我们遇到的情况

我们发现,当从数据库中检索数据时,有时数字会以字符串形式显示给 json_encode,从而导致值周围出现双引号。

这可能导致 JavaScript 函数出现问题,这些函数期望值为数字。

当我们检索包含序列化数组的数据库字段时发现了这一点。在对其进行反序列化并将其发送到 json_encode 函数后,原始数组中的数字值现在被视为字符串,并在其周围显示双引号。

修复方法:在编码数组之前,将其发送到一个函数,该函数检查数字类型并进行相应的转换。从那时起编码按预期工作。
0
diagnose at gmail dot com
8天前
小心尾随的反斜杠!

JSON 规范*不允许*在字符串中使用尾随反斜杠。它将创建一个 JSON 编码的字符串,而不会抛出错误,但此字符串在解析时会导致错误。

例如,字符串“Example\”在 JavaScript 中解析时会导致以下错误

JSON.parse: expected ',' or '}' after property value in object

这似乎是 JSON 规范中的一个疏忽,唯一的解决方法是在编码之前从所有字符串中删除尾随反斜杠。
0
dassolucas at c238 dot com dot ar
1个月前
问题
---------------
当您使用 array_filter 过滤 PHP 中的数组时,会保留原始键。如果删除元素,最终会在键中出现间隙(不连续)。当编码为 JSON 时,这会导致列表被解释为 JSON 对象而不是 JSON 数组,这可能不是您的 JavaScript 代码所期望的。

解决方案
---------------
在这种情况下,array_values() 函数至关重要。它使用连续的数字键(0、1、2、...)重新索引数组,确保 JSON 输出始终是格式良好的数组。

示例
----------
<?php

// 用例:过滤列表并确保一致的 JSON 数组输出

// 想象您有一个项目列表,需要使用 JSON 将过滤后的版本发送到 JavaScript 前端
// 。您希望确保过滤后的列表始终以 JSON 数组的形式接收,
// 无论删除了哪些项目。

// 示例数据:项目列表
$items = [
"first",
"second",
"third",
"fourth",
"fifth"
];

// 要从列表中删除的项目
$itemsToRemove = ["second", "fourth"];

// 过滤列表,保留原始键(成为不连续的)
$filteredItems = array_filter($items, function($item) use ($itemsToRemove) {
return !
in_array($item, $itemsToRemove);
});

// 准备 JSON 输出数据
$output_arr = [
"list" => $filteredItems
];

// 输出 1:具有不连续键的 JSON(成为对象)
echo "Output without array_values:\n";
echo
json_encode($output_arr, JSON_PRETTY_PRINT) . "\n\n";
/* 输出:
{
"list": {
"0": "first",
"2": "third",
"4": "fifth"
}
}
*/

// 使用 array_values 重置键以使其连续
$output_arr['list'] = array_values($output_arr['list']);

// 输出 2:具有连续键的 JSON(保持为数组)
echo "Output with array_values:\n";
echo
json_encode($output_arr, JSON_PRETTY_PRINT) . "\n";
/* 输出:
{
"list": [
"first",
"third",
"fifth"
]
}
*/
?>
3
guilhenfsu at gmail dot com
11年前
UTF-8 特殊字符的解决方案。

<?

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

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

//编码
$json = html_entity_decode(json_encode($array));

//输出:{"nome":"Paição","cidade":"São Paulo"}
echo $json;

?>
2
Sam Barnum
15年前
请注意,如果您尝试编码包含非 UTF 值的数组,则生成的 JSON 字符串中将出现空值。您可以使用 array_map 函数批量编码数组的所有元素
<?php
$encodedArray
= array_map(utf8_encode, $rawArray);
?>
0
Walter Tross
9年前
如果您需要美观的输出,但希望缩进为 2 个空格而不是 4 个

$json_indented_by_4 = json_encode($output, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
$json_indented_by_2 = preg_replace('/^( +?)\\1(?=[^ ])/m', '$1', $json_indented_by_4);
To Top