JSON — json_encode, json_decode

~12 daq · PHP · Fayllar, Sana va Xatolar

Muammodan boshlaylik

PHP serveringiz React frontend, mobil ilova yoki Telegram bot bilan gaplashishi kerak. Ular PHP massivini tushunmaydi. Siz esa JavaScript ob'ektini tushunmaysiz.

Ikki dastur bir-birini tushunishi uchun umumiy til kerak. Bugungi vebda bu til — JSON (JavaScript Object Notation). Har qanday dasturlash tili uni o'qiy va yoza oladi.


JSON qanday ko'rinadi

{
    "id": 42,
    "ism": "Dilshod",
    "faol": true,
    "telefon": null,
    "teglar": ["php", "mysql"],
    "manzil": {
        "shahar": "Toshkent",
        "tuman": "Chilonzor"
    }
}

PHP massiviga juda o'xshaydi. Qoidalar qat'iy:

  • Kalitlar — faqat qo'shtirnoqda ("ism", 'ism' emas)
  • Matnlar — faqat "..."
  • Oxirgi elementdan keyin vergul yo'q
  • Izoh yozib bo'lmaydi

PHP → JSON: json_encode

<?php

$user = [
    'id'     => 42,
    'ism'    => "O'tkir",
    'faol'   => true,
    'teglar' => ['php', 'mysql'],
];

echo json_encode($user);
// {"id":42,"ism":"O'tkir","faol":true,"teglar":["php","mysql"]}

Indeksli massiv → JSON massiv [...], assotsiativ → JSON ob'ekt {...}.

Foydali bayroqlar

<?php

$data = ['shahar' => 'Тошкент', 'url' => 'https://devdocs.uz/php'];

echo json_encode($data);
// {"shahar":"Тошкент","url":"https:\/\/devdocs.uz\/php"}

echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
{
    "shahar": "Тошкент",
    "url": "https://devdocs.uz/php"
}
Bayroq Nima qiladi
JSON_UNESCAPED_UNICODE Kirill va maxsus harflar \u... ga aylanmaydi
JSON_UNESCAPED_SLASHES / belgisi \/ ga aylanmaydi
JSON_PRETTY_PRINT Chiroyli formatlash (o'qish uchun)
JSON_THROW_ON_ERROR Xato bo'lsa — exception tashlaydi

JSON → PHP: json_decode

<?php

$json = '{"id":42,"ism":"Dilshod","teglar":["php","mysql"]}';

$data = json_decode($json, true);   // true — assotsiativ massiv qaytaradi

echo $data['ism'];          // Dilshod
echo $data['teglar'][0];    // php

[!WARNING] Ikkinchi parametr true ni unutmang. Busiz json_decode massiv emas, ob'ekt (stdClass) qaytaradi va $data['ism'] xato beradi — $data->ism deb yozish kerak bo'ladi. Ko'pchilik loyihalarda massiv bilan ishlash odat.


Xatolarni ushlash

Noto'g'ri JSON berilsa, json_decode jimgina null qaytaradi:

<?php

$data = json_decode('{"ism": "Ali",}', true);   // oxirgi vergul — xato
var_dump($data);   // NULL

Lekin null — to'g'ri JSON ham bo'lishi mumkin (json_decode('null')). Shuning uchun aniq tekshirish kerak:

<?php

try {
    $data = json_decode($json, true, flags: JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo "JSON xato: " . $e->getMessage();   // Syntax error
}

Qoida: yangi kodda doim JSON_THROW_ON_ERROR ishlating. Exception lar haqida 27-darsda.


API dan kelgan JSON ni o'qish

Frontend fetch bilan JSON yuborganda

JavaScript:

fetch('/api/buyurtma.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ mahsulot_id: 5, soni: 2 }),
});

PHP da bu $_POST ga tushmaydi! $_POST faqat forma formatini tushunadi. JSON tanani qo'lda o'qish kerak:

<?php

$tana = file_get_contents('php://input');
$data = json_decode($tana, true, flags: JSON_THROW_ON_ERROR);

$mahsulotId = (int) ($data['mahsulot_id'] ?? 0);
$soni = (int) ($data['soni'] ?? 1);

php://input — so'rovning xom tanasi.

Boshqa API ga so'rov yuborish

<?php

$javob = file_get_contents('https://api.github.com/repos/php/php-src', false, stream_context_create([
    'http' => ['header' => "User-Agent: devdocs\r\n"],
]));

$repo = json_decode($javob, true);
echo $repo['stargazers_count'];

Haqiqiy loyihalarda buning uchun curl yoki Guzzle kutubxonasi ishlatiladi (39-dars, Composer).


JSON faylda sozlamalar saqlash

<?php

$yol = __DIR__ . '/sozlamalar.json';

// O'qish
$sozlama = is_file($yol)
    ? json_decode(file_get_contents($yol), true, flags: JSON_THROW_ON_ERROR)
    : ['til' => 'uz', 'mavzu' => 'yorug'];

// O'zgartirish
$sozlama['mavzu'] = 'qorongi';

// Saqlash
file_put_contents(
    $yol,
    json_encode($sozlama, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
    LOCK_EX
);

Nozik joylar

Bo'sh massiv:

<?php

echo json_encode([]);                       // []  — massiv
echo json_encode(new stdClass());           // {}  — ob'ekt
echo json_encode([], JSON_FORCE_OBJECT);    // {}

Frontend {} kutayotgan bo'lsa-yu, siz [] yuborsangiz — xato chiqishi mumkin.

Teshikli indekslar:

<?php

$a = [0 => 'a', 2 => 'c'];   // 1 yo'q (masalan, array_filter dan keyin)
echo json_encode($a);         // {"0":"a","2":"c"} — massiv emas, ob'ekt!
echo json_encode(array_values($a));   // ["a","c"]

Float aniqligi: json_encode(0.1 + 0.2) → 0.30000000000000004. Pulni JSON da ham butun son (tiyin) sifatida yuboring.


Nima uchun shunday?

Nima uchun XML emas, JSON g'olib bo'ldi?

2000-yillarda ma'lumot almashish uchun XML ishlatilgan. U kuchli, lekin og'ir: <ism>Ali</ism> — nom ikki marta yoziladi. JSON esa JavaScript ob'ekt sintaksisidan olingan — brauzer uni hech qanday kutubxonasiz tushunadi, hajmi kichik, odam uchun ham o'qishli. AJAX va REST API lar ommalashgach, JSON tabiiy standartga aylandi.


Xulosa

Eslab qoling:

  • json_encode($massiv, JSON_UNESCAPED_UNICODE) — PHP → JSON
  • json_decode($json, true) — JSON → assotsiativ massiv (true ni unutmang)
  • JSON_THROW_ON_ERROR — xatoni jimgina yutib yubormaslik uchun
  • fetch dan kelgan JSON $_POST da emas — file_get_contents('php://input')
  • array_filter dan keyin array_values() — aks holda ob'ekt bo'lib ketadi

Keyingi dars

26-dars: Sana va vaqt — date(), DateTime, timezone