في هذا الدرس 6تصفّح المواضيع
يرسل PHP افتراضياً نوع المحتوى text/html؛ لذا يجب على كل نقطة نهاية JSON API الإعلان صراحةً عن header("Content-Type: application/json; charset=utf-8") قبل طباعة أي بيانات.
- يُخبر ضبط رأس
Content-Typeالمتصفحات وعملاءfetch()وأدوات الاختبار بأن جسم الاستجابة هو كائن JSON. - اجمع بين العلمين
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHESفيjson_encode()لتبقى النصوص العربية والروابط مقروءة بوضوح. - استدعِ دالة
header()دائماً قبل طباعة أي مخرجات لتجنب خطأ إرسال الرؤوس مسبقاً.
يحافظ العلم JSON_UNESCAPED_UNICODE على ظهور الأحرف العربية بوضوح بدلاً من رموز \u0645...، ويمنع JSON_UNESCAPED_SLASHES تهريب الشرطات المائلة.
<?php
// In HTTP SAPI: header('Content-Type: application/json; charset=utf-8');
$payload = [
'ok' => true,
'message' => 'Welcome to PHP 8.4 JSON API',
'docs' => 'https://closetag.com/tutorials/php',
];
echo json_encode(
$payload,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
) . "\n";
عندما يرسل العميل طلباً بنوع محتوى Content-Type: application/json، لا يملأ PHP مصفوفة $_POST تلقائياً! بل يجب قراءة جسم الطلب الخام عبر مجرى الإدخال php://input.
- تُملأ مصفوفة
$_POSTفقط عندما يكون الطلب مرسلاً بترميز النماذج التقليديةurlencodedأوmultipart/form-data. - اقرأ نص JSON الخام من جسم الطلب باستخدام
$raw = file_get_contents("php://input"). - حلل النص بأمان داخل كتلة
try / catch (JsonException $e)عبر الدالةjson_decode($raw, true, 512, JSON_THROW_ON_ERROR).
يؤدي تمرير true كمعامل ثانٍ إلى إرجاع مصفوفة ترابطية، بينما يضمن العلم JSON_THROW_ON_ERROR إطلاق استثناء JsonException عند وجود خطأ نحوي في JSON.
<?php
// Simulated raw body read from file_get_contents('php://input')
$rawBody = '{"title":"REST API Guide","views":450}';
try {
$input = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
echo "Decoded Title : " . ($input['title'] ?? 'N/A') . "\n";
echo "Decoded Views : " . ($input['views'] ?? 0) . "\n";
} catch (JsonException $e) {
http_response_code(400);
echo "400 Invalid JSON: " . $e->getMessage() . "\n";
}
لا تُرجع الواجهات البرمجية الاحترافية الرمز 200 OK عند حدوث خطأ؛ بل تستخدم دالة http_response_code($code) لإرسال رمز الحالة الدقيق المعبر عن النتيجة.
- استخدم الرمز
200 OKلنجاح الجلب أو التحديث، والرمز201 Createdعند نجاح إنشاء سجل جديد في قاعدة البيانات. - استخدم
400لخطأ صياغة الطلب، و401لعدم تسجيل الدخول، و403لنقص الصلاحيات، و404لعدم وجود السجل. - استخدم الرمز
422 Unprocessable Contentعندما تكون صياغة JSON سليمة لكن قيم الحقول تخالف شروط التحقق.
يضبط استدعاء http_response_code(201) حالة الاستجابة إلى 201 Created، بينما يُرجع استدعاؤها بدون معاملات الرقم المضبوط حالياً.
<?php
function respondCreated(array $record): string {
http_response_code(201);
return json_encode([
'ok' => true,
'code' => http_response_code(),
'data' => $record,
]);
}
echo respondCreated(['id' => 91, 'slug' => 'php-rest-json-endpoints']) . "\n";
تعتمد تطبيقات الواجهة الأمامية وتطبيقات الهواتف على هيكل استجابة JSON ثابت ومتوقع في جميع المسارات، سواء نجح الطلب أم فشل.
- وحّد المفاتيح العليا للاستجابة مثل
{"ok": bool, "data": mixed, "error": ?string, "errors": array}. - أنشئ دالة مساعدة موحدة
jsonResponse(array $payload, int $status = 200)لإرسال الرأس ورمز الحالة والـ JSON معاً. - لا تكشف أبداً نصوص استعلامات SQL أو مسارات ملفات الخادم الداخلية ضمن رسائل الخطأ المرسلة للعميل في بيئة الإنتاج.
تشترك استجابتا النجاح والفشل في نفس المفاتيح العليا تماماً (ok وdata وerror)، مما يمنع أخطاء الخصائص غير المعرفة في الواجهة.
<?php
function buildApiEnvelope(bool $ok, mixed $data = null, ?string $err = null): string {
return json_encode([
'ok' => $ok,
'data' => $data,
'error' => $err,
], JSON_UNESCAPED_UNICODE);
}
echo buildApiEnvelope(true, ['user_id' => 12]) . "\n";
echo buildApiEnvelope(false, null, 'Unauthorized token') . "\n";
عندما تعمل الواجهة الأمامية على نطاق مختلف (مثل https://app.example.com) عن نطاق خادم PHP API (https://api.example.com)، يفرض المتصفح سياسة مشاركة الموارد العابرة للمجالات (CORS).
- أرسل الرأس
Access-Control-Allow-Origin: https://app.example.com، وتجنب استخدام النجمة*في المسارات التي تتطلب مصادقة. - ترسل المتصفحات طلب استكشاف مسبق بطريقة
OPTIONS(Preflight) قبل إرسال طلباتPOSTبصيغة JSON عبر النطاقات. - عندما تكون طريقة الطلب
$_SERVER["REQUEST_METHOD"] === "OPTIONS"، أرسل رؤوس CORS المسموحة واضبط الرمز204وأنهِ التنفيذ فوراً.
يتيح فحص النطاق $origin مقابل قائمة بيضاء محددة السماح لعدة واجهات موثوقة دون فتح الـ API للمواقع المجهولة.
<?php
$allowedOrigins = ['https://app.closetag.com', 'http://localhost:3000'];
$origin = 'https://app.closetag.com';
if (in_array($origin, $allowedOrigins, true)) {
echo "Access-Control-Allow-Origin: $origin\n";
echo "Access-Control-Allow-Methods: GET, POST, OPTIONS\n";
echo "Access-Control-Allow-Headers: Content-Type, Authorization\n";
}
استخدم هذا الجدول المرجعي لربط كل حالة في واجهات PHP البرمجية برمز استجابة HTTP القياسي المقابل لها.
- تشير رموز الفئة 2xx إلى استلام الطلب وفهمه وتنفيذه بنجاح.
- تشير رموز الفئة 4xx إلى خطأ من جهة العميل (مدخلات غير صالحة أو غياب المصادقة أو مسار غير موجود).
- تشير رموز الفئة 5xx إلى عطل غير متوقع من جهة الخادم (مثل تعذر الاتصال بقاعدة البيانات).
يربط تعبير match في PHP 8 أرقام رموز الحالة بأوصافها القياسية في بروتوكول HTTP بنظافة ووضوح.
| رمز الحالة | المعنى القياسي | متى يُرسل في واجهة PHP API |
|---|---|---|
200 | OK | Successful GET, PUT, or PATCH with JSON body |
201 | Created | POST created a new database resource |
204 | No Content | Successful DELETE or CORS OPTIONS preflight |
400 | Bad Request | Malformed JSON syntax in php://input |
401 / 403 | Unauthorized / Forbidden | Missing auth token (401) or insufficient role (403) |
422 | Unprocessable Content | Valid JSON syntax, but field validation failed |
<?php
function statusLabel(int $code): string {
return match ($code) {
200 => '200 OK',
201 => '201 Created',
204 => '204 No Content',
400 => '400 Bad Request',
422 => '422 Unprocessable Content',
default => "$code Status",
};
}
echo statusLabel(201) . " | " . statusLabel(422) . "\n";
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
استخدم هذا الجدول المرجعي لربط كل حالة في واجهات PHP البرمجية برمز استجابة HTTP القياسي المقابل لها. تشير رموز الفئة 2xx إلى استلام الطلب وفهمه وتنفيذه بنجاح. تشير رموز الفئة 4xx إلى خطأ من جهة العميل (مدخلات غير صالحة أو غياب المصادقة أو مسار غير موجود). تشير رموز الفئة 5xx إلى عطل غير متوقع من جهة الخادم (مثل تعذر الاتصال بقاعدة البيانات).
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 JSON API Endpoints بناء JSON API
- ابنِ نقاط نهاية JSON احترافية في PHP 8 باستخدام رؤوس نوع المحتوى وقراءة المجرى php://input ودالة http_response_code.
- للمراجعة
- 02 Setting application/json Headers ضبط نوع الاستجابة application/json في PHP
- المفهوم الأساسي لقسم ضبط نوع الاستجابة application/json في PHP في لغة PHP الحديثة.
- للمراجعة
- 03 Reading Raw JSON from php://input قراءة جسم الطلب JSON عبر المجرى php://input
- الصياغة البرمجية والتطبيق العملي المباشر لقسم قراءة جسم الطلب JSON عبر المجرى php://input.
- للمراجعة
- 04 Sending Semantic HTTP Response Codes إرسال رموز الحالة القياسية بـ http_response_code
- قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم إرسال رموز الحالة القياسية بـ http_response_code.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 PHP PHP
- PHP: Hypertext Preprocessor
- لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
- للمراجعة
- 02 CLI CLI
- Command-Line Interface
- واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
- للمراجعة
- 03 FPM FPM
- FastCGI Process Manager
- مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
- للمراجعة
- 04 HTML HTML
- HyperText Markup Language
- لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم ضبط نوع الاستجابة application/json في PHP للتحقق من المخرجات.
-
بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم قراءة جسم الطلب JSON عبر المجرى php://input وقارن مخرجات التنفيذ.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
أي رأس استجابة HTTP يجب أن يرسله ملف PHP ليتعرف العميل على جسم الاستجابة ككائن JSON بترميز UTF-8؟
يعلن هذا الرأس نوع المحتوى القياسي لبيانات JSON وترميز المحارف UTF-8.
لماذا تكون مصفوفة $_POST فارغة عندما يرسل عميل Fetch API طلب POST بنوع محتوى Content-Type: application/json؟
تُقرأ بيانات application/json عبر file_get_contents("php://input") ثم تحلل بـ json_decode().
كيف تحلل نص JSON خام في PHP 8 بحيث يؤدي أي خطأ في الصياغة إلى إطلاق استثناء يمكن اصطياده؟
يطلق العلم JSON_THROW_ON_ERROR استثناء JsonException عند فشل التحليل، وترجع true مصفوفة ترابطية.
ما رمز حالة HTTP القياسي الذي يجب أن ترجعه واجهة REST API عند نجاح طلب POST في إنشاء سجل جديد؟
يشير الرمز 201 Created قياسياً إلى نجاح إنشاء مورد جديد.
ما رمز حالة HTTP الأنسب عندما يرسل العميل كائن JSON سليم الصياغة لكن أحد الحقول مثل "email" يفشل في التحقق؟
يدل الرمز 422 على سلامة صياغة JSON مع فشل التحقق المنطقي من قيم الحقول.
أي علم في دالة json_encode() يحافظ على بقاء الأحرف العربية مقروءة بدلاً من تحويلها لتسلسلات \u06xx؟
يحتفظ العلم JSON_UNESCAPED_UNICODE بالأحرف متعددة البايت بترميز UTF-8 كما هي.
كيف يجب أن يتعامل مسار PHP API مع طلب الاستكشاف المسبق CORS المرسل بطريقة OPTIONS؟
يفحص طلب OPTIONS صلاحيات النطاق فقط قبل أن يرسل المتصفح الطلب الفعلي.
ما الدالة التي أُضيفت في PHP 8.3 للتحقق من صحة نص JSON دون استهلاك الذاكرة في بناء مصفوفات أو كائنات؟
تتحقق دالة json_validate() من سلامة صياغة JSON بسرعة وباستهلاك ذاكرة أقل.