json_decode($json, true) הופכת מחרוזת JSON לערכי PHP, כשכל אובייקט JSON הופך למערך אסוציאטיבי. השמיטו את true ואובייקטי JSON יהפכו במקום זאת לאובייקטי stdClass, שקוראים עם ->. JSON לא תקין נותן null.
פלט:
Ada
js
Ada
php
Array
(
[name] => Ada
[age] => 36
[langs] => Array
(
[0] => php
[1] => js
)
[admin] => 1
)
מערכי JSON תמיד הופכים לרשימות PHP, בכל מצב שתבחרו. הכיוון ההפוך, מ-PHP ל-JSON, הוא json_encode().
מערך אסוציאטיבי או אובייקט: true מול false
שני המצבים מחזיקים את אותם נתונים; בחרו את זה שנקרא טוב יותר בקוד שלכם. מערכים עובדים עם כל פונקציית מערך (array_column, array_map, isset($data['key'])), ולכן רוב הקוד מעביר true. אובייקטים צריכים את תחביר הסוגריים המסולסלים למפתחות שאינם שמות מאפיינים תקינים, כמו מפתחות עם מקף או מספר:
פלט:
Ada zero London
Ada zero London
object(stdClass)#2 (1) {
["city"]=>
string(6) "London"
}
הפרמטר הרביעי מקבל דגלים. JSON_OBJECT_AS_ARRAY נותן גם הוא מערכים, אבל רק כל עוד הארגומנט השני הוא null (ברירת המחדל שלו): json_decode($json, flags: JSON_OBJECT_AS_ARRAY) מחזירה מערכים, בעוד json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY) עדיין מחזירה אובייקטים.
מעבר על JSON מקונן
תשובות של API הן בדרך כלל רשימה של אובייקטים בתוך אובייקט. פענחו פעם אחת, ואז עברו עליה עם foreach, והשתמשו ב-?? לשדות שעשויים לחסור:
פלט:
#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
[1] => Ada
[2] => Linus
[3] => Grace
)
טיפול ב-JSON לא תקין
json_decode() מחזירה null ל-JSON לא תקין, אבל null הוא גם התוצאה הנכונה לטקסט ה-JSON null, ולכן null לבדו לא אומר לכם אם היא נכשלה. json_last_error_msg() נותנת את הסיבה של הקריאה האחרונה. הדרך הנקייה יותר היא JSON_THROW_ON_ERROR, שזורק JsonException:
פלט:
NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error
הארגומנט השלישי, 512, הוא עומק הקינון המקסימלי (ברירת המחדל). עם ארגומנטים בשם אפשר לדלג עליו: json_decode($json, true, flags: JSON_THROW_ON_ERROR).
בדיקה אם מחרוזת היא JSON תקין עם json_validate()
PHP 8.3 הוסיפה את json_validate(). היא עונה true או false בלי לבנות את המערכים המפוענחים, ולכן היא משתמשת בפחות זיכרון מפענוח כשכל מה שצריך הוא כן או לא, למשל כדי לדחות גוף בקשה מוקדם:
פלט:
'{"a": 1}' valid
'[1, 2, 3]' valid
'"text"' valid
'{a: 1}' invalid: Syntax error
'{\'a\': 1}' invalid: Syntax error
'' invalid: Syntax error
אם תשתמשו בנתונים בכל מקרה, דלגו על json_validate() ופענחו עם JSON_THROW_ON_ERROR: אימות קודם מפענח את המחרוזת פעמיים.
קריאת קובץ JSON
קראו את הקובץ עם file_get_contents() ופענחו את המחרוזת. הבלוק הזה כותב קודם את settings.json כדי שיהיה קובץ לקרוא:
פלט:
Theme: dark
Plugins: 2
{
"theme": "dark",
"fontSize": 16,
"plugins": [
"git",
"lint"
]
}
למה json_decode מחזירה null: הסיבות הרגילות
JSON מחמיר יותר מתחביר המערכים של JavaScript ושל PHP. כל מחרוזת למטה נראית סבירה וכל אחת מחזירה null. הריצו כדי לראות את הסיבה לכל אחת, ואז תקנו אחת והריצו שוב:
פלט:
single quotes Syntax error
unquoted key Syntax error
trailing comma Syntax error
comment Syntax error
byte order mark Syntax error
too deep Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"
byte order mark בלתי נראה ברוב העורכים, והוא הסיבה הקלאסית לכך שקובץ JSON "נראה בסדר" אבל לא מתפענח. הסירו אותו עם $text = preg_replace('/^\xEF\xBB\xBF/', '', $text); לפני הפענוח.
שאלות נפוצות
איך ממירים JSON למערך ב-PHP?
העבירו true כארגומנט השני: json_decode('{"name":"Ada"}', true) מחזירה ['name' => 'Ada'], ולכן קוראים ערכים עם $data['name']. בלי true, אובייקטי JSON הופכים לאובייקטי stdClass וכותבים $data->name.
למה json_decode מחזירה null?
ה-JSON לא תקין (גרשיים בודדים, פסיק בסוף, מפתחות בלי מירכאות, byte order mark), הוא מקונן עמוק יותר ממגבלת העומק, או שה-JSON באמת הוא null. בדקו את json_last_error_msg(), או פענחו עם JSON_THROW_ON_ERROR כדי לקבל JsonException עם הסיבה.
איך בודקים אם מחרוזת היא JSON תקין ב-PHP?
מאז PHP 8.3, json_validate($string) מחזירה true או false בלי לבנות את הערך המפוענח. בגרסאות ישנות יותר, פענחו ובדקו json_last_error() === JSON_ERROR_NONE.
איך קוראים קובץ JSON ב-PHP?
קראו את הקובץ, ואז פענחו אותו: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. file_get_contents() מחזירה false אם הקובץ חסר, אז בדקו את זה קודם.
איך ניגשים למפתח JSON עם מקף ב-PHP?
פענחו למערך והשתמשו ב-$data['first-name'], או עם אובייקטים השתמשו בסוגריים מסולסלים: $obj->{'first-name'}. אותו תחביר סוגריים עובד למפתחות שהם מספרים, כמו $obj->{'0'}.