2024 年 PHP Conference Japan

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 實作了原始 » RFC 7159 中指定的 JSON 的超集。

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
"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"}

範例 #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."移除一個鍵值的循序陣列".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 編碼器,如果輸入 value字串整數浮點數布林值json_encode() 將會產生一個簡單值(即非物件也非陣列)的 JSON。雖然大多數解碼器會接受這些值作為有效的 JSON,但有些解碼器可能不會,因為規範在這一點上模稜兩可。

總而言之,務必測試您的 JSON 解碼器是否可以處理從 json_encode() 產生的輸出。

參見

新增註解

使用者貢獻的註解 11 則註解

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 時要小心,它可能會弄亂您的資料!
elliseproduction at gmail dot com
2 年前
請注意,JSON_FORCE_OBJECT 會將所有非關聯式陣列轉換為物件。對於空陣列來說,這不一定是個好解決方案。
如果您只想將空陣列轉換為物件,只需在使用 json_encode 函式之前將它們轉換為空物件即可。

例如

<?php

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

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

?>
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);
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'" 之類的設定。
ryan at ryanparman dot com
14 年前
我遇到了在 SimpleXML 物件上執行 json_encode() 時會忽略 CDATA 的「bug」。我查閱了 http://bugs.php.net/42001http://bugs.php.net/41976,雖然我同意發文者的看法,認為文件應該說明像這樣的陷阱,但我還是找到了解決方法。

您需要將 SimpleXML 物件轉換回 XML 字串,然後使用 LIBXML_NOCDATA 選項將其重新導入 SimpleXML。完成此操作後,您就可以使用 json_encode() 並仍然取回 CDATA。

<?php
// 假設我們已經將一個複雜的 SimpleXML 物件儲存在 $xml 中
$json = json_encode(new SimpleXMLElement($xml->asXML(), LIBXML_NOCDATA));
?>
Garrett
16 年前
關於 json_encode 自動將數字加上引號的注意事項

json_encode 函式似乎會注意值的資料類型。讓我解釋一下我們遇到的情況

我們發現從資料庫檢索資料時,有時數字會以字串的形式出現在 json_encode 中,導致值前後加上雙引號。

這可能會導致 JavaScript 函式中出現問題,因為這些函式預期值是數值。

這是當我們從資料庫中檢索包含序列化陣列的欄位時發現的。在將它們反序列化並通過 json_encode 函式發送後,原始陣列中的數值現在被視為字串,並在其周圍顯示雙引號。

解決方法:在編碼陣列之前,將其發送到一個檢查數值類型並進行相應轉換的函式。之後的編碼即可按預期工作。
diagnose at gmail dot com
8 天前
小心結尾的反斜線!

JSON 規範*不允許*字串中出現結尾的反斜線。它會建立一個 JSON 編碼的字串,但不會拋出錯誤,但是這個字串在解析時會導致錯誤。

例如,字串「Example\」在 JavaScript 中解析時會導致以下錯誤

JSON.parse: expected ',' or '}' after property value in object(JSON.parse:在物件的屬性值後預期出現 ',' 或 '}')

這似乎是 JSON 規範中的疏忽,唯一的解決方法似乎是在編碼之前從所有字串中移除結尾的斜線。
dassolucas at c238 dot com dot ar
1 個月前
問題
---------------
在 PHP 中使用 array_filter 過濾陣列時,會保留原始鍵。如果移除元素,鍵中會出現間隙(非連續)。編碼為 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 "沒有使用 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 "使用 array_values 的輸出:\n";
echo
json_encode($output_arr, JSON_PRETTY_PRINT) . "\n";
/* 輸出:
{
"list": [
"first",
"third",
"fifth"
]
}
*/
?>
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;

?>
Sam Barnum
15 年前
請注意,如果您嘗試編碼包含非 UTF 值的陣列,則在產生的 JSON 字串中會得到空值。您可以使用 `array_map` 函數批量編碼陣列的所有元素。
<?php
$encodedArray
= array_map(utf8_encode, $rawArray);
?>
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