طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 132 · تقنيات تطوير الواجهات الخلفية
الدرس 13 · الوحدة 6: الدمج مع الخدمات وواجهات برمجة التطبيقات

JSON: لغة تبادل البيانات

حين يكون العميل برنامجًا لا إنسانًا: بيانات بدل صفحات. ⏱ نحو 30 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تشرح صيغة JSON وتقابلها مع أنواع PHP.
  • تحوّل البيانات بـ json_encode و json_decode مع الخيارات المناسبة للعربية.
  • تكتب نقطة API ترد بـ JSON وترويسة Content-Type صحيحة.
  • تستقبل JSON من جسم الطلب عبر php://input وتتعامل مع JSON المعطوب.

١لماذا JSON؟

حتى الآن كان الخادم يرد بصفحات HTML يقرؤها الإنسان. لكن كثيرًا من «العملاء» ليسوا بشرًا: تطبيق جوال (مقرر 251)، أو واجهة React (مقرر 242)، أو خادم آخر. هؤلاء يريدون بيانات منظمة لا صفحة منسّقة. وأشهر صيغة لذلك JSON (تُنطق «جيسون»): نص بسيط يشبه كائنات JavaScript التي عرفتها في 131:

{  "id": 7,  "name": "قهوة عربية",  "price": 35.5,  "available": true,  "tags": ["مشروبات", "سعودي"],  "supplier": { "name": "مزارع جازان", "city": "جازان" }}
قيمة JSONتقابلها في PHP
كائن { "a": 1 }مصفوفة ترابطية ['a' => 1]
مصفوفة [1, 2]مصفوفة مفهرسة [1, 2]
نص "..." وعدد وقيم true / false / nullstring و int/float و bool و null

قواعد JSON صارمة: المفاتيح بين علامتي تنصيص مزدوجتين دائمًا، ولا فاصلة زائدة بعد آخر عنصر، ولا تعليقات.

٢من PHP إلى JSON: json_encode

<?php$product = [    'id' => 7,    'name' => 'قهوة عربية',    'price' => 35.5,    'available' => true,    'tags' => ['مشروبات', 'سعودي'],]; echo json_encode($product) . "\n\n";echo json_encode($product, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);

٣استجابة JSON حقيقية

الواجهة التي ترد بـ JSON تخبر العميل بنوع المحتوى عبر الترويسة Content-Type: application/json، وإلا ظنها HTML. هذه أول «واجهة برمجة» API تكتبها:

<?phpheader('Content-Type: application/json; charset=utf-8'); $products = [    ['id' => 1, 'name' => 'قهوة عربية', 'price' => 35],    ['id' => 2, 'name' => 'تمر سكري', 'price' => 45],    ['id' => 3, 'name' => 'شاي أخضر', 'price' => 18],]; $max = isset($_GET['max']) ? (float) $_GET['max'] : null;if ($max !== null) {    $products = array_values(array_filter($products, fn($p) => $p['price'] <= $max));} echo json_encode(['count' => count($products), 'data' => $products], JSON_UNESCAPED_UNICODE);

المختبر ينسّق JSON تلقائيًّا في تبويب المصدر لأن نوعه application/json. و array_filter مع دالة سهمية fn تختار المنتجات التي سعرها لا يتجاوز max، و array_values تعيد ترقيمها.

٤من JSON إلى PHP: json_decode

والاتجاه المعاكس: نص JSON يصل من طلب أو ملف أو خدمة أخرى، فنحوّله إلى مصفوفة PHP. لاحظ المعامل الثاني true: بدونه تعيد الدالة كائنات بدل مصفوفات ترابطية:

<?php$text = '{"student":"نورة","grades":[90, 85, 77],"active":true}'; $data = json_decode($text, true);echo $data['student'] . "\n";echo array_sum($data['grades']) / count($data['grades']) . "\n"; // JSON معطوب$bad = json_decode('{"name": "سعود",}', true);var_dump($bad);echo json_last_error_msg();

إن كان النص غير صالح تعيد json_decode القيمة null، وتشرح json_last_error_msg() السبب. وفي PHP الحديث يمكنك طلب استثناء بالخيار JSON_THROW_ON_ERROR.

٥استقبال JSON في الطلب

التطبيقات الحديثة ترسل بياناتها JSON في جسم الطلب بدل النماذج. هنا لا تملأ PHP مصفوفة $_POST؛ بل تقرأ الجسم الخام من php://input وتفك ترميزه بنفسك:

<?phpheader('Content-Type: application/json; charset=utf-8'); $in = json_decode(file_get_contents('php://input'), true);if (!is_array($in) || empty($in['items'])) {    http_response_code(400);    echo json_encode(['error' => 'أرسل JSON فيه items'], JSON_UNESCAPED_UNICODE);    exit;} $total = 0;foreach ($in['items'] as $it) {    $total += $it['price'] * $it['qty'];}http_response_code(201);echo json_encode(['customer' => $in['customer'] ?? 'زائر', 'total' => $total], JSON_UNESCAPED_UNICODE);

الأخطاء أيضًا تعود JSON برمز مناسب، فيفهمها البرنامج العميل بسهولة. جرّب في المختبر «📮 طلب يدوي» مع نوع البيانات JSON.

توقّع وتحقّق

لتحويل مصفوفة PHP إلى نص JSON:

encode = ترميز.

ما فائدة JSON_UNESCAPED_UNICODE؟

بدل \uXXXX.

json_decode($t, true) تعيد:

بسبب المعامل true.

من أين نقرأ JSON المرسل في جسم الطلب؟

الجسم الخام.

الخلاصة

تحدٍّ برمجي: واجهة إحصاءات الدرجات

متوسط

اكتب stats.php: تستقبل POST بجسم JSON فيه مصفوفة درجات، وترد بإحصاءاتها JSON.

المطلوب:
  • الطلب: {"grades": [90, 70, 80]} والرد: {"count":3,"avg":80,"max":90,"min":70} برمز 200.
  • المتوسط مقرّب لخانتين بـ round.
  • إن لم يكن الجسم JSON صالحًا أو لم تكن grades مصفوفة غير فارغة: رمز 400 والرد {"error":"grades مطلوبة"}.
  • الترويسة Content-Type: application/json في كل الردود.
👀 اعرض الاستجابة المطلوبة
✓ التحقق الآلي: يرسل المختبر هذه الطلبات إلى خادمك بالترتيب ثم يفحص الاستجابات
  1. POST /stats.php ({"grades": [90, 70, 80]})
  2. POST /stats.php ({"grades": [95, 88, 72, 61]})
  3. POST /stats.php ({"grades": []})
  4. POST /stats.php (درجات)
  • الكود يعمل بلا أخطاء أو تحذيرات
  • [90,70,80] ← count 3 و avg 80 و max 90 و min 70
  • [95,88,72,61] ← avg 79
  • نوع المحتوى application/json
  • مصفوفة فارغة ← 400
  • مصفوفة فارغة ← {"error":"grades مطلوبة"}
  • نص ليس JSON ← 400
  • تقرأ جسم الطلب من php://input

💡 تلميح 1
$in = json_decode(file_get_contents('php://input'), true);
💡 تلميح 2
اختبر الشرط !is_array($g) || count($g) === 0 قبل أي حساب.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

<?phpheader('Content-Type: application/json; charset=utf-8');$in = json_decode(file_get_contents('php://input'), true);$g = $in['grades'] ?? null; if (!is_array($g) || count($g) === 0) {    http_response_code(400);    echo json_encode(['error' => 'grades مطلوبة'], JSON_UNESCAPED_UNICODE);    exit;}echo json_encode([    'count' => count($g),    'avg' => round(array_sum($g) / count($g), 2),    'max' => max($g),    'min' => min($g),]);
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس