إرجاع JSON من PHP: دليل سريع وخالٍ من الأخطاء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تصحيح أخطاء API بسرعة: لماذا يعيد PHP نص HTML بدلاً من JSON؟

\n\n

هل سبق لك أن جلست في الساعة الثالثة فجرًا، تحدق في شاشة Postman الفارغة وتتساءل: "لماذا يعيد سكريبت PHP الخاص بي نص HTML بدلاً من JSON؟" إذا كان الأمر كذلك، فأنت لست وحدك. موضوع إرجاع JSON من سكريبت PHP على Stack Overflow حصد عشرات الآلاف من المشاهدات، وهذا ليس من قبيل الصدفة. كل مطور مبتدئ في الواجهة الخلفية يقع في نفس الأخطاء: نسيان الرؤوس، إخراج غير مرغوب فيه، نوع محتوى خاطئ.

\n\n

في هذه المقالة، لن نكتفي بنسخ إجابة من منتدى. سنقوم بتحليل كيفية إرجاع JSON من PHP بشكل صحيح وسريع وبدون مفاجآت. ستتعرف على لماذا قد يخذلك exit(json_encode($data))، وكيف توفر أجزاء من الثانية في عملية التسلسل، وماذا تفعل إذا تعطل JSON فجأة.

\n\n

هل أنت مستعد؟ لنبدأ.

\n\n

تشريح استجابة JSON الصحيحة

\n\n

لنبدأ بالأساسيات. إليك كيف لا يجب أن تفعل:

\n\n
<?php\n$data = ['status' => 'ok', 'message' => 'مرحباً!'];\necho json_encode($data);\n?>
\n\n

لماذا هذا سيء؟ أولاً، لا يوجد رأس Content-Type. قد يفسر المتصفح أو العميل الاستجابة على أنها HTML أو نص. ثانيًا، إذا كان هناك أي مسافة أو echo أو تحذير في الكود قبل ذلك، فسينكسر JSON.

\n\n

القالب البسيط الصحيح يبدو هكذا:

\n\n
<?php\nheader('Content-Type: application/json; charset=utf-8');\n$data = ['status' => 'ok', 'message' => 'مرحباً!'];\necho json_encode($data, JSON_UNESCAPED_UNICODE);\nexit;\n?>
\n\n

لاحظ استخدام JSON_UNESCAPED_UNICODE — فهو يحافظ على النص العربي مقروءًا، بدلاً من تحويله إلى \\u0645\\u0631\\u062D\\u0628\\u0627. و exit هو ضمان ضد أي إخراج عشوائي بعد الاستجابة.

\n\n

الرؤوس: ليس فقط Content-Type

\n\n

لـ تحسين أداء JSON، أضف رأسين إضافيين:

\n\n
header('Content-Type: application/json; charset=utf-8');\nheader('X-Content-Type-Options: nosniff');\nheader('Cache-Control: no-cache, must-revalidate');
\n\n

X-Content-Type-Options: nosniff يمنع المتصفح من "تخمين" نوع المحتوى — وهذا يعزز الأمان. أما Cache-Control فهو مفيد للبيانات الديناميكية، لضمان عدم تخزين العميل لاستجابة قديمة.

\n\n

معالجة الأخطاء: عندما تفشل دالة json_encode

\n\n

الدالة json_encode ترجع false عند الفشل. وهنا يبدأ الجزء المثير للاهتمام. إذا قمت ببساطة بـ echo json_encode($data) وحصلت على سلسلة فارغة — سيصاب العميل بالحيرة.

\n\n

تحقق دائمًا من النتيجة:

\n\n
$json = json_encode($data, JSON_UNESCAPED_UNICODE);\nif ($json === false) {\n    http_response_code(500);\n    echo json_encode(['error' => 'فشل ترميز JSON: ' . json_last_error_msg()]);\n    exit;\n}\necho $json;\nexit;
\n\n

بالمناسبة، json_last_error_msg() سيعيد رسالة واضحة: "Malformed UTF-8 characters" أو "Inf and NaN cannot be JSON encoded". هذا سيوفر لك ساعات من التصحيح.

\n\n

البيانات المتداخلة بعمق والتكرار

\n\n

مشكلة أخرى هي المراجع الدائرية في الكائنات. إذا قمت بتمرير كائن به مراجع متبادلة، فستتسبب الدالة json_encode في خطأ. الحل: استخدام JSON_PARTIAL_OUTPUT_ON_ERROR أو تحويل الكائن إلى مصفوفة مسبقًا.

\n\n
$json = json_encode($complexObject, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);
\n\n

ولكن كن حذرًا: الإخراج الجزئي قد يكون غير مكتمل. من الأفضل إصلاح بنية البيانات.

\n\n

تحسين أداء JSON في PHP

\n\n

الآن ننتقل إلى الجزء الأكثر إثارة — كيفية تسريع إرجاع JSON من PHP.

\n\n

1. التخزين المؤقت لـ JSON المسلسل

\n\n

إذا كانت البيانات تتغير نادرًا (قواميس، إعدادات، قائمة مدن)، فلا تقم بتسلسلها في كل مرة. احفظ JSON الجاهز في ملف، Memcached

المدونات

توصيات الكتب