بي أتش بي:كيفية إرسال رمز استجابة HTTP؟
-
16-09-2020 - |
سؤال
لدي برنامج نصي PHP يحتاج إلى تقديم استجابات باستخدام رموز استجابة HTTP (رموز الحالة)، مثل HTTP 200 OK، أو بعض أكواد 4XX أو 5XX.
كيف يمكنني القيام بذلك في PHP؟
المحلول
لقد وجدت هذا السؤال للتو واعتقدت أنه يحتاج إلى إجابة أكثر شمولاً:
اعتبارا من بي إتش بي 5.4 هناك ثلاث طرق لتحقيق ذلك:
تجميع رمز الاستجابة بنفسك (PHP >= 4.0)
ال header()
تحتوي الوظيفة على حالة استخدام خاصة تكتشف سطر استجابة HTTP وتتيح لك استبداله بآخر مخصص
header("HTTP/1.1 200 OK");
ومع ذلك، فإن هذا يتطلب معاملة خاصة لـ (Fast)CGI PHP:
$sapi_type = php_sapi_name();
if (substr($sapi_type, 0, 3) == 'cgi')
header("Status: 404 Not Found");
else
header("HTTP/1.1 404 Not Found");
ملحوظة: بحسب ال HTTP RFC, ، ال عبارة السبب يمكن أن تكون أي سلسلة مخصصة (تتوافق مع المعيار)، ولكن من أجل توافق العميل I لا أوصي بوضع سلسلة عشوائية هناك.
ملحوظة: php_sapi_name()
يتطلب بي إتش بي 4.0.1
الوسيطة الثالثة لوظيفة الرأس (PHP >= 4.3)
من الواضح أن هناك بعض المشاكل عند استخدام هذا البديل الأول.أكبر ما أعتقد أنه تم تحليله جزئيًا بواسطة PHP أو خادم الويب وتم توثيقه بشكل سيئ.
منذ 4.3، header
تحتوي الدالة على وسيطة ثالثة تتيح لك تعيين رمز الاستجابة بشكل مريح إلى حد ما، ولكن استخدامها يتطلب أن تكون الوسيطة الأولى سلسلة غير فارغة.هنا خياران:
header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
أوصي بالثاني.الأول يفعل العمل على جميع المتصفحات التي قمت باختبارها، ولكن قد تواجه بعض المتصفحات الثانوية أو برامج زحف الويب مشكلة في سطر الرأس الذي يحتوي على نقطتين فقط.اسم حقل الرأس في الثاني.البديل بالطبع ليس موحدًا بأي شكل من الأشكال ويمكن تعديله، لقد اخترت للتو اسمًا وصفيًا على أمل.
وظيفة http_response_code (PHP >= 5.4)
ال http_response_code()
تم تقديم الوظيفة في PHP 5.4، وقد صنعت الأشياء كثيراً أسهل.
http_response_code(404);
هذا كل شئ.
التوافق
إليك وظيفة قمت بإعدادها عندما كنت بحاجة إلى التوافق مع الإصدار الأقل من 5.4 ولكني أردت وظيفة "الجديدة" http_response_code
وظيفة.أعتقد أن PHP 4.3 أكثر من كافٍ للتوافق مع الإصدارات السابقة، لكنك لا تعرف أبدًا...
// For 4.3.0 <= PHP <= 5.4.0
if (!function_exists('http_response_code'))
{
function http_response_code($newcode = NULL)
{
static $code = 200;
if($newcode !== NULL)
{
header('X-PHP-Response-Code: '.$newcode, true, $newcode);
if(!headers_sent())
$code = $newcode;
}
return $code;
}
}
نصائح أخرى
لسوء الحظ، وجدت أن الحلول المقدمة من @dualed بها عيوب مختلفة.
استخدام
substr($sapi_type, 0, 3) == 'cgi'
لا يكفي لاكتشاف CGI السريع.عند استخدام PHP-FPM FastCGI Process Manager،php_sapi_name()
إرجاع التيار الوطني الحر وليس CGIيكشف Fasctcgi وphp-fpm عن خطأ آخر ذكره @Josh - باستخدام
header('X-PHP-Response-Code: 404', true, 404);
يعمل بشكل صحيح ضمن PHP-FPM (FastCGI)header("HTTP/1.1 404 Not Found");
قد يفشل عندما لا يكون البروتوكول HTTP/1.1 (أي."HTTP/1.0").يجب اكتشاف البروتوكول الحالي باستخدام$_SERVER['SERVER_PROTOCOL']
(متوفر منذ PHP 4.1.0هناك حالتان على الأقل عند الاتصال
http_response_code()
يؤدي إلى سلوك غير متوقع:- عندما تواجه PHP رمز استجابة HTTP لا تفهمه، ستستبدل PHP الرمز برمز تعرفه من نفس المجموعة.على سبيل المثال، يتم استبدال "521 خادم الويب معطل" بـ "500 خطأ داخلي في الخادم".يتم التعامل مع العديد من رموز الاستجابة غير الشائعة الأخرى من المجموعات الأخرى 2xx، 3xx، 4xx بهذه الطريقة.
- على خادم مزود بوظيفة php-fpm وnginx http_response_code() قد يغير الرمز كما هو متوقع ولكن ليس الرسالة.قد ينتج عن هذا رأس غريب "404 OK" على سبيل المثال.تم ذكر هذه المشكلة أيضًا على موقع PHP من خلال تعليق المستخدم http://www.php.net/manual/en/function.http-response-code.php#112423
كمرجع لك، توجد قائمة كاملة برموز حالة استجابة HTTP (تتضمن هذه القائمة رموزًا من معايير إنترنت IETF بالإضافة إلى طلبات IETF RFCs الأخرى.العديد منها غير مدعوم حاليًا بواسطة وظيفة PHP http_response_code): http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
يمكنك بسهولة اختبار هذا الخطأ عن طريق الاتصال:
http_response_code(521);
سيرسل الخادم رمز استجابة HTTP "500 خطأ داخلي في الخادم" مما يؤدي إلى حدوث أخطاء غير متوقعة إذا كان لديك على سبيل المثال تطبيق عميل مخصص يتصل بالخادم الخاص بك ويتوقع بعض رموز HTTP الإضافية.
الحل الخاص بي (لجميع إصدارات PHP منذ 4.1.0):
$httpStatusCode = 521;
$httpStatusMsg = 'Web server is down';
$phpSapiName = substr(php_sapi_name(), 0, 3);
if ($phpSapiName == 'cgi' || $phpSapiName == 'fpm') {
header('Status: '.$httpStatusCode.' '.$httpStatusMsg);
} else {
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
header($protocol.' '.$httpStatusCode.' '.$httpStatusMsg);
}
خاتمة
لا يدعم تنفيذ http_response_code() جميع رموز استجابة HTTP وقد يحل محل رمز استجابة HTTP المحدد برمز آخر من نفس المجموعة.
لا تحل وظيفة http_response_code() الجديدة جميع المشكلات المتضمنة ولكنها تجعل الأمور أسوأ من خلال تقديم أخطاء جديدة.
حل "التوافق" الذي تقدمه @dualed لا يعمل كما هو متوقع، على الأقل في ظل PHP-FPM.
تحتوي الحلول الأخرى التي تقدمها @dualed أيضًا على العديد من الأخطاء.لا يتعامل اكتشاف CGI السريع مع PHP-FPM.يجب اكتشاف البروتوكول الحالي.
هي موضع تقدير أي اختبارات وتعليقات.
منذ PHP 5.4، يمكنك استخدام GreetacodicetAchcode للحصول على رمز حالة الرأس وتعيينه.
هنا مثال:
giveacodicetagpre.هنا هو وثيقة هذه الوظيفة في php.net:
أضف هذا السطر قبل أي إخراج من الجسم، في الحدث لا تستخدم التخزين المؤقت الإخراج.
giveacodicetagpre.استبدل جزء الرسالة ("موافق") بالرسالة المناسبة ورمز الحالة مع التعليمات البرمجية حسب الاقتضاء (404 و 501 وما إلى ذلك)
إذا كنت هنا بسبب إعطاء WordPress 404 عند تحميل البيئة، يجب أن يصل هذا إلى حل المشكلة:
giveacodicetagpre.المشكلة ترجع إليها إرسال الحالة: 404 غير موجود رأس.يجب عليك تجاوز ذلك. هذا سيعمل أيضا:
giveacodicetagpre.باستخدام رأس الوظيفة.هناك مثال في القسم الموجود في المعلمة الأولى التي يستغرقها
إذا كان الإصدار الخاص بك من PHP لا يتضمن هذه الوظيفة:
giveacodicetagpre.We can get different return value from http_response_code via the two different environment:
- Web Server Environment
- CLI environment
At the web server environment, return previous response code if you provided a response code or when you do not provide any response code then it will be print the current value. Default value is 200 (OK).
At CLI Environment, true will be return if you provided a response code and false if you do not provide any response_code.
Example of Web Server Environment of Response_code's return value:
var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)
Example of CLI Environment of Response_code's return value:
var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");
http_response_code(200); not work because test alert 404 https://developers.google.com/speed/pagespeed/insights/