Tôi có một tập lệnh PHP cần thực hiện các phản hồi với mã phản hồi HTTP (mã trạng thái), như HTTP 200 OK hoặc một số mã 4XX hoặc 5XX.
Làm thế nào tôi có thể làm điều này trong PHP?
Tôi có một tập lệnh PHP cần thực hiện các phản hồi với mã phản hồi HTTP (mã trạng thái), như HTTP 200 OK hoặc một số mã 4XX hoặc 5XX.
Làm thế nào tôi có thể làm điều này trong PHP?
Câu trả lời:
Tôi chỉ tìm thấy câu hỏi này và nghĩ rằng nó cần một câu trả lời toàn diện hơn:
Kể từ phiên bản PHP 5.4, có ba phương thức để thực hiện điều này:
Các header()
chức năng có một tình huống đặc biệt mà phát hiện một dòng phản ứng HTTP và cho phép bạn thay thế mà với một tùy chỉnh
header("HTTP/1.1 200 OK");
Tuy nhiên, điều này đòi hỏi phải xử lý đặc biệt cho CGI (Nhanh) CGI:
$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");
Lưu ý: Theo HTTP RFC , cụm từ lý do có thể là bất kỳ chuỗi tùy chỉnh nào (phù hợp với tiêu chuẩn), nhưng vì mục đích tương thích của khách hàng, tôi không khuyên bạn nên đặt một chuỗi ngẫu nhiên ở đó.
Lưu ý: php_sapi_name()
yêu cầu PHP 4.0.1
Rõ ràng có một vài vấn đề khi sử dụng biến thể đầu tiên đó. Cái lớn nhất mà tôi nghĩ là nó được phân tích cú pháp một phần bởi PHP hoặc máy chủ web và tài liệu kém.
Kể từ 4.3, header
hàm có đối số thứ 3 cho phép bạn đặt mã phản hồi một cách thoải mái, nhưng sử dụng nó đòi hỏi đối số đầu tiên phải là một chuỗi không trống. Đây là hai lựa chọn:
header(':', true, 404);
header('X-PHP-Response-Code: 404', true, 404);
Tôi khuyên bạn nên thứ 2 . Cái đầu tiên không hoạt động trên tất cả các trình duyệt tôi đã thử nghiệm, nhưng một số trình duyệt nhỏ hoặc trình thu thập dữ liệu web có thể có vấn đề với dòng tiêu đề chỉ chứa dấu hai chấm. Tên trường tiêu đề trong 2. biến thể tất nhiên là không được tiêu chuẩn hóa theo bất kỳ cách nào và có thể được sửa đổi, tôi chỉ chọn một tên mô tả hy vọng.
Các http_response_code()
chức năng được giới thiệu trong PHP 5.4, và nó làm cho mọi việc rất nhiều dễ dàng hơn.
http_response_code(404);
Đó là tất cả.
Đây là một chức năng mà tôi đã thực hiện khi tôi cần khả năng tương thích dưới 5,4 nhưng muốn chức năng của chức năng "mới" http_response_code
. Tôi tin rằng PHP 4.3 là quá đủ khả năng tương thích ngược, nhưng bạn không bao giờ biết ...
// 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;
}
}
headers_sent()
luôn luôn đúng sau khi gọi header()
? (2) có bao giờ tìm thấy bất cứ điều gì như http_response lòng () trong thế giới 5.4 không? Ít nhất là tiêu đề cũ () có thể ảnh hưởng đến văn bản sau mã trạng thái.
headers_sent()
là đúng nếu bạn không thể thêm bất kỳ tiêu đề nào nữa vì nội dung đã được gửi, không phải nếu bạn đã thêm tiêu đề. (2) Xin lỗi, không. Các ngôn ngữ khác có sự hỗ trợ tốt hơn
http_response_code
(và có thể nói chung là sửa đổi tiêu đề) sẽ không hoạt động nữa sau khi bạn làm echo
điều gì đó. Hy vọng nó giúp.
Thật không may, tôi thấy các giải pháp được trình bày bởi @dualed có nhiều sai sót.
Sử dụng substr($sapi_type, 0, 3) == 'cgi'
không phải là enogh để phát hiện CGI nhanh. Khi sử dụng Trình quản lý quy trình FastCGI PHP-FPM, php_sapi_name()
trả về fpm không phải cgi
Fasctcgi và php-fpm phơi bày một lỗi khác được đề cập bởi @Josh - sử dụng header('X-PHP-Response-Code: 404', true, 404);
không hoạt động đúng theo PHP-FPM (FastCGI)
header("HTTP/1.1 404 Not Found");
có thể thất bại khi giao thức không phải là HTTP / 1.1 (tức là 'HTTP / 1.0'). Giao thức hiện tại phải được phát hiện bằng cách sử dụng$_SERVER['SERVER_PROTOCOL']
(có sẵn từ PHP 4.1.0
Có ít nhất 2 trường hợp khi gọi http_response_code()
kết quả trong hành vi không mong muốn:
Để bạn tham khảo ở đây có danh sách đầy đủ các mã trạng thái phản hồi HTTP (danh sách này bao gồm các mã từ các tiêu chuẩn internet của IETF cũng như các RFC IETF khác. Nhiều trong số chúng hiện không được hỗ trợ bởi chức năng http_response_code của PHP): http: //en.wikipedia .org / wiki / List_of_HTTP_status_codes
Bạn có thể dễ dàng kiểm tra lỗi này bằng cách gọi:
http_response_code(521);
Máy chủ sẽ gửi mã phản hồi HTTP "500 lỗi máy chủ nội bộ" dẫn đến các lỗi không mong muốn nếu bạn có một ứng dụng khách tùy chỉnh gọi máy chủ của bạn và mong đợi một số mã HTTP bổ sung.
Giải pháp của tôi (cho tất cả các phiên bản PHP kể từ 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);
}
Phần kết luận
Việc triển khai http_response_code () không hỗ trợ tất cả các mã phản hồi HTTP và có thể ghi đè mã phản hồi HTTP được chỉ định bằng một mã khác từ cùng một nhóm.
Hàm http_response_code () mới không giải quyết được tất cả các vấn đề liên quan nhưng làm cho mọi thứ trở nên tồi tệ nhất khi đưa ra các lỗi mới.
Giải pháp "tương thích" được cung cấp bởi @dualed không hoạt động như mong đợi, ít nhất là theo PHP-FPM.
Các giải pháp khác được cung cấp bởi @dualed cũng có nhiều lỗi khác nhau. Phát hiện CGI nhanh không xử lý PHP-FPM. Giao thức hiện tại phải được phát hiện.
Bất kỳ bài kiểm tra và ý kiến được đánh giá cao.
kể từ PHP 5.4, bạn có thể sử dụng http_response_code()
để lấy và đặt mã trạng thái tiêu đề.
đây là một ví dụ:
<?php
// Get the current response code and set a new one
var_dump(http_response_code(404));
// Get the new response code
var_dump(http_response_code());
?>
đây là tài liệu của hàm này trong php.net:
Thêm dòng này trước bất kỳ đầu ra nào của thân máy, trong trường hợp bạn không sử dụng bộ đệm đầu ra.
header("HTTP/1.1 200 OK");
Thay thế phần thông báo ('OK') bằng thông báo phù hợp và mã trạng thái bằng mã của bạn nếu phù hợp (404, 501, v.v.)
Nếu bạn ở đây vì Wordpress cho 404 khi tải môi trường, điều này sẽ khắc phục sự cố:
define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
status_header( 200 );
//$wp_query->is_404=false; // if necessary
Vấn đề là do nó gửi tiêu đề Trạng thái: 404 Không tìm thấy. Bạn phải ghi đè lên điều đó. Điều này cũng sẽ làm việc:
define('WP_USE_THEMES', false);
require('../wp-blog-header.php');
header("HTTP/1.1 200 OK");
header("Status: 200 All rosy");
header("HTTP/1.1 200 OK");
http_response_code(201);
header("Status: 200 All rosy");
http_response_code (200); không hoạt động vì cảnh báo kiểm tra 404 https://developers.google.com/speed/pagespeed/insights/
Nếu phiên bản PHP của bạn không bao gồm chức năng này:
<?php
function http_response_code($code = NULL) {
if ($code !== NULL) {
switch ($code) {
case 100: $text = 'Continue';
break;
case 101: $text = 'Switching Protocols';
break;
case 200: $text = 'OK';
break;
case 201: $text = 'Created';
break;
case 202: $text = 'Accepted';
break;
case 203: $text = 'Non-Authoritative Information';
break;
case 204: $text = 'No Content';
break;
case 205: $text = 'Reset Content';
break;
case 206: $text = 'Partial Content';
break;
case 300: $text = 'Multiple Choices';
break;
case 301: $text = 'Moved Permanently';
break;
case 302: $text = 'Moved Temporarily';
break;
case 303: $text = 'See Other';
break;
case 304: $text = 'Not Modified';
break;
case 305: $text = 'Use Proxy';
break;
case 400: $text = 'Bad Request';
break;
case 401: $text = 'Unauthorized';
break;
case 402: $text = 'Payment Required';
break;
case 403: $text = 'Forbidden';
break;
case 404: $text = 'Not Found';
break;
case 405: $text = 'Method Not Allowed';
break;
case 406: $text = 'Not Acceptable';
break;
case 407: $text = 'Proxy Authentication Required';
break;
case 408: $text = 'Request Time-out';
break;
case 409: $text = 'Conflict';
break;
case 410: $text = 'Gone';
break;
case 411: $text = 'Length Required';
break;
case 412: $text = 'Precondition Failed';
break;
case 413: $text = 'Request Entity Too Large';
break;
case 414: $text = 'Request-URI Too Large';
break;
case 415: $text = 'Unsupported Media Type';
break;
case 500: $text = 'Internal Server Error';
break;
case 501: $text = 'Not Implemented';
break;
case 502: $text = 'Bad Gateway';
break;
case 503: $text = 'Service Unavailable';
break;
case 504: $text = 'Gateway Time-out';
break;
case 505: $text = 'HTTP Version not supported';
break;
default:
exit('Unknown http status code "' . htmlentities($code) . '"');
break;
}
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
header($protocol . ' ' . $code . ' ' . $text);
$GLOBALS['http_response_code'] = $code;
} else {
$code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200);
}
return $code;
}
Chúng tôi có thể nhận được giá trị trả về khác nhau từ http_response_code thông qua hai môi trường khác nhau:
Ở môi trường máy chủ web, trả về mã phản hồi trước đó nếu bạn đã cung cấp mã phản hồi hoặc khi bạn không cung cấp bất kỳ mã phản hồi nào thì nó sẽ được in giá trị hiện tại. Giá trị mặc định là 200 (OK).
Tại Môi trường CLI, true sẽ được trả về nếu bạn cung cấp mã phản hồi và false nếu bạn không cung cấp bất kỳ answer_code nào.
Ví dụ về môi trường máy chủ Web của giá trị trả về của answer_code:
var_dump(http_respone_code(500)); // int(200)
var_dump(http_response_code()); // int(500)
Ví dụ về giá trị trả về của môi trường CLI của Feedback_code:
var_dump(http_response_code()); // bool(false)
var_dump(http_response_code(501)); // bool(true)
var_dump(http_response_code()); // int(501)
header('X-PHP-Response-Code: 404', true, 404);
nó hoạt động đúng theo PHP-FPM (FastCGI)