2024 日本 PHP 研討會

預定義常數

以下常數由此擴充功能定義,並且只有在擴充功能已編譯到 PHP 中或在執行階段動態載入時才會可用。

以下常數表示 json_last_error() 返回的錯誤類型,或儲存為 JsonExceptioncode

JSON_ERROR_NONE (整數)
沒有發生錯誤。
JSON_ERROR_DEPTH (整數)
已超過最大堆疊深度。
JSON_ERROR_STATE_MISMATCH (整數 (int))
發生於下溢位或模式不匹配時。
JSON_ERROR_CTRL_CHAR (整數 (int))
控制字元錯誤,可能編碼錯誤。
JSON_ERROR_SYNTAX (整數 (int))
語法錯誤。
JSON_ERROR_UTF8 (整數 (int))
UTF-8 字元格式錯誤,可能編碼錯誤。
JSON_ERROR_RECURSION (整數 (int))
傳遞給 json_encode() 的物件或陣列包含遞迴參考,因此無法編碼。如果提供了 JSON_PARTIAL_OUTPUT_ON_ERROR 選項,則會在遞迴參考的位置編碼 null (空值)。
JSON_ERROR_INF_OR_NAN (整數 (int))
傳遞給 json_encode() 的值包含 NAN (非數值) 或 INF (無限大)。如果提供了 JSON_PARTIAL_OUTPUT_ON_ERROR 選項,則會將這些特殊數字編碼為 0
JSON_ERROR_UNSUPPORTED_TYPE (整數 (int))
傳遞給 json_encode() 的值是不支援的類型,例如 資源。如果提供了 JSON_PARTIAL_OUTPUT_ON_ERROR 選項,則會將不支援的值編碼為 null (空值)。
JSON_ERROR_INVALID_PROPERTY_NAME (整數 (int))
將 JSON 物件解碼為 PHP 物件時,傳遞給 json_decode() 的字串中,有一個鍵值以 \u0000 字元開頭。
JSON_ERROR_UTF16 (整數 (int))
傳遞給 json_decode() 的 JSON 字串中包含的 unicode 跳脫字元中,存在單個未配對的 UTF-16 代理項。

以下常數可以組合起來形成 json_decode() 的選項。

JSON_BIGINT_AS_STRING (整數 (int))
將大整數解碼為其原始字串值。
JSON_OBJECT_AS_ARRAY (整數 (int))
將 JSON 物件解碼為 PHP 陣列。這個選項可以透過呼叫 json_decode() 並將第二個參數設定為 true (真) 來自動新增。

以下常數可以組合起來,形成 json_encode() 的選項。

JSON_HEX_TAG (整數)
所有 < 和 > 都會轉換成 \u003C 和 \u003E。
JSON_HEX_AMP (整數)
所有 & 都會轉換成 \u0026。
JSON_HEX_APOS (整數)
所有 ' 都會轉換成 \u0027。
JSON_HEX_QUOT (整數)
所有 " 都會轉換成 \u0022。
JSON_FORCE_OBJECT (整數)
當使用非關聯式陣列時,輸出一個物件而不是陣列。尤其在輸出接收端預期接收物件且陣列為空時非常有用。
JSON_NUMERIC_CHECK (整數)
將數字字串編碼為數字。
JSON_PRETTY_PRINT (整數)
在返回的資料中使用空格進行格式化。
JSON_UNESCAPED_SLASHES (整數)
不跳脫 /
JSON_UNESCAPED_UNICODE (整數)
直接編碼多位元組 Unicode 字元(預設會跳脫為 \uXXXX)。
JSON_PARTIAL_OUTPUT_ON_ERROR (整數)
替換一些無法編碼的值,而不是產生錯誤。
JSON_PRESERVE_ZERO_FRACTION (整數)
確保 浮點數 值永遠被編碼為浮點數值。
JSON_UNESCAPED_LINE_TERMINATORS (整數)
當提供 JSON_UNESCAPED_UNICODE 時,行尾符號不會被跳脫。它的行為與 PHP 7.1 之前沒有此常數時的行為相同。PHP 7.1.0 起可用。

以下常數可以組合起來,形成 json_decode()json_encode() 的選項。

JSON_INVALID_UTF8_IGNORE (整數)
忽略無效的 UTF-8 字元。PHP 7.2.0 起可用。
JSON_INVALID_UTF8_SUBSTITUTE (整數)
將無效的 UTF-8 字元轉換為 \0xfffd(Unicode 字元「替換字元」)。PHP 7.2.0 起可用。
JSON_THROW_ON_ERROR (整數)
如果發生錯誤,會拋出 JsonException 異常,而不是設定全域錯誤狀態,該狀態可透過 json_last_error()json_last_error_msg() 取得。JSON_PARTIAL_OUTPUT_ON_ERROR 的優先順序高於 JSON_THROW_ON_ERROR。PHP 7.3.0 版本起可用。
JSON_ERROR_NON_BACKED_ENUM (整數)
傳遞給 json_encode() 的值包含無法序列化的非支援列舉。PHP 8.1.0 版本起可用。
新增註解

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

majid4466 at gmail dot com
8 年前
要取得真正乾淨的 JSON 字串,請像這樣使用這三個常數

<?php
$array
= ['€', 'http://example.com/some/cool/page', '337'];
$bad = json_encode($array);
$good = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);

// $bad 的結果會是 ["\u20ac","http:\/\/example.com\/some\/cool\/page","337"]
// $good 的結果會是 ["€","http://example.com/some/cool/page",337]
?>
Yzmir Ramirez
10 年前
如果您好奇常數的數值,在 JSON 1.2.1 中,常數具有以下值(並非建議您直接使用這些數字)

JSON_HEX_TAG => 1
JSON_HEX_AMP => 2
JSON_HEX_APOS => 4
JSON_HEX_QUOT => 8
JSON_FORCE_OBJECT => 16
JSON_NUMERIC_CHECK => 32
JSON_UNESCAPED_SLASHES => 64
JSON_PRETTY_PRINT => 128
JSON_UNESCAPED_UNICODE => 256

JSON_ERROR_DEPTH => 1
JSON_ERROR_STATE_MISMATCH => 2
JSON_ERROR_CTRL_CHAR => 3

JSON_ERROR_SYNTAX => 4

JSON_ERROR_UTF8 => 5
JSON_OBJECT_AS_ARRAY => 1

JSON_BIGINT_AS_STRING => 2
nikospapoutsis
2 年前
使用 majid4466 at gmail dot com 提供的程式碼或一般情況下的 JSON_NUMERIC_CHECK 時要格外小心。

例如,在 PHP 7.4 和 8.1 中,當 precision: 14 且 serialize_precision: -1 時,我們會得到

<?php
$array
= ['€', 55.6666666666666666, 'http://example.com/some/cool/page', '000337', '55.6666666666666666'];
echo
$case1 = json_encode($array);
echo
$case2 = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
echo
$case3 = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);

[
"\u20ac",55.666666666666664,"http:\/\/example.com\/some\/cool\/page","000337","55.6666666666666666"]
// 在 $case1 中,歐元符號和網址都改變了,但我們的未加引號的浮點數也損失了一位數(由於精確度)

["€",55.666666666666664,"http://example.com/some/cool/page","000337","55.6666666666666666"]
// 在 $case2 中,歐元符號和網址都保持不變,但我們的未加引號的浮點數仍然損失了一位數(由於精確度)

["€",55.666666666666664,"http://example.com/some/cool/page",337,55.666666666666664]
// 在 $case3 中,我們再次保留了歐元符號和網址,但這次不僅我們的未加引號的浮點數損失了一位數,
// 加引號的浮點數也發生了同樣的情況,而且數字/字串也失去了它的前導零

另外請注意,在 PHP 5.x 中,您可能會得到一些不同但同樣錯誤的結果,因為預設值可能不同,而且一些函數的內部也發生了變化。
ASchmidt at Anamera dot net
6 年前
在多維陣列中,JSON_FORCE_OBJECT 會將所有巢狀的數字陣列編碼為物件。

如果您只關心第一層陣列(例如,使其適用於 MySQL JSON 欄位),您可以將第一層陣列轉換為物件,例如:

<?php
$json
= json_encode( (object) $array, JSON_PRESERVE_ZERO_FRACTION+JSON_UNESCAPED_UNICODE );
?>

或者,如果您有大陣列並且擔心物件轉換的開銷,您可以在陣列大小之外附加一個「null」值,這將強制陣列變為關聯式陣列

<?php
$beyond
= count( $array ) + 1;
if ( !
array_key_exists( $beyond, $array) )
$array[ $beyond ] = NULL;
$json = json_encode( $array, JSON_PRESERVE_ZERO_FRACTION+JSON_UNESCAPED_UNICODE );
?>

當然,如果您之後的程式碼會迭代這個陣列,則必須將值為「NULL」的元素視為與「!isset()」相同。
eduard dot amoros dot wahl at gmail dot com
2 個月前
關於 JSON_NUMERIC_CHECK 和科學記號法的警告。

JSON_NUMERIC_CHECK 會移除科學記號法。因此,
json_encode(['scientificNumber' => '1e-4'], JSON_NUMERIC_CHECK);
會回傳 {"scientificNumber":0.0001}

您必須考慮到這一點,因為它可能會讓使用科學記號法的目的失效。
匿名
6 年前
在 php 7+ 中,旗標 JSON_NUMERIC_CHECK 和 JSON_PRESERVE_ZERO_FRACTION 已失效 — json_encode((float)8.8) 會回傳 "8.8000000000000007",而 json_encode((float)8.8, JSON_NUMERIC_CHECK) 和 json_encode((float)8.8, JSON_PRESERVE_ZERO_FRACTION) 也會回傳 "8.8000000000000007"。

修正此問題的唯一方法是在 php.ini 中設定 "serialize_precision = -1"。
To Top