http_response_code() 函数用于获取或设置 HTTP 响应状态码。
HTTP 状态码是服务器对客户端请求的响应状态的三位数字代码。该函数提供了一种简单的方式来设置或检索当前的 HTTP 响应状态码。
header() 函数来设置状态码。
http_response_code ( int $response_code = ? ) : int|bool
| 参数 | 类型 | 描述 |
|---|---|---|
$response_code |
int |
可选的。要设置的 HTTP 响应状态码。
|
| 返回值 | 描述 |
|---|---|
| int |
当不传递参数时:返回当前的 HTTP 响应状态码。
当传递参数时:返回之前的状态码。 |
true |
当传递参数且成功设置状态码,但之前没有状态码时返回 true。
|
false |
如果传递了无效的状态码,或者头信息已经发送导致无法设置状态码时返回 false。
|
| 状态码 | 类别 | 描述 |
|---|---|---|
200 |
成功 | OK - 请求成功 |
301 |
重定向 | Moved Permanently - 永久重定向 |
302 |
重定向 | Found - 临时重定向 |
304 |
重定向 | Not Modified - 资源未修改 |
400 |
客户端错误 | Bad Request - 请求无效 |
401 |
客户端错误 | Unauthorized - 需要认证 |
403 |
客户端错误 | Forbidden - 禁止访问 |
404 |
客户端错误 | Not Found - 资源未找到 |
405 |
客户端错误 | Method Not Allowed - 方法不允许 |
500 |
服务器错误 | Internal Server Error - 服务器内部错误 |
502 |
服务器错误 | Bad Gateway - 错误的网关 |
503 |
服务器错误 | Service Unavailable - 服务不可用 |
以下示例展示了如何获取和设置 HTTP 响应状态码。
<?php
// 获取当前状态码(默认是200)
$current_code = http_response_code();
echo "当前HTTP状态码: " . $current_code . "\n";
// 设置404状态码
$previous_code = http_response_code(404);
echo "之前的状态码: " . $previous_code . "\n";
echo "新的状态码: " . http_response_code() . "\n";
// 设置500状态码
http_response_code(500);
echo "当前状态码: " . http_response_code() . "\n";
// 重置为200
http_response_code(200);
?>
根据不同的错误设置相应的 HTTP 状态码。
<?php
// 假设根据某些条件显示错误页面
$error_type = 'not_found'; // 可以是 'not_found', 'forbidden', 'server_error' 等
switch ($error_type) {
case 'not_found':
http_response_code(404);
$error_message = "页面未找到";
break;
case 'forbidden':
http_response_code(403);
$error_message = "禁止访问";
break;
case 'server_error':
http_response_code(500);
$error_message = "服务器内部错误";
break;
default:
http_response_code(400);
$error_message = "错误的请求";
}
// 输出错误页面
echo "<!DOCTYPE html>\n";
echo "<html>\n";
echo "<head>\n";
echo " <title>错误 " . http_response_code() . " - " . $error_message . "</title>\n";
echo "</head>\n";
echo "<body>\n";
echo " <h1>" . http_response_code() . " - " . $error_message . "</h1>\n";
echo " <p>抱歉,请求的页面出现问题。</p>\n";
echo "</body>\n";
echo "</html>\n";
?>
在 REST API 中使用不同的 HTTP 状态码表示不同的操作结果。
<?php
// 设置响应头为JSON
header('Content-Type: application/json');
// 模拟API请求处理
$method = $_SERVER['REQUEST_METHOD'];
$request_data = json_decode(file_get_contents('php://input'), true);
// 处理不同的请求方法
switch ($method) {
case 'GET':
// 获取资源
$resource_id = $_GET['id'] ?? null;
if ($resource_id === '123') {
http_response_code(200);
echo json_encode([
'id' => 123,
'name' => '示例资源',
'status' => 'active'
]);
} else {
http_response_code(404);
echo json_encode([
'error' => '资源未找到',
'message' => '请求的资源不存在'
]);
}
break;
case 'POST':
// 创建资源
if (!empty($request_data)) {
http_response_code(201); // 201 Created
echo json_encode([
'id' => 456,
'message' => '资源创建成功',
'data' => $request_data
]);
} else {
http_response_code(400);
echo json_encode([
'error' => '无效的请求',
'message' => '请求体不能为空'
]);
}
break;
case 'PUT':
// 更新资源
http_response_code(200);
echo json_encode([
'message' => '资源更新成功',
'data' => $request_data
]);
break;
case 'DELETE':
// 删除资源
http_response_code(204); // 204 No Content
// 204状态码不返回任何内容
break;
default:
http_response_code(405); // 405 Method Not Allowed
header('Allow: GET, POST, PUT, DELETE');
echo json_encode([
'error' => '方法不允许',
'message' => '只支持 GET, POST, PUT, DELETE 方法'
]);
}
?>
展示 http_response_code() 与使用 header() 函数设置状态码的区别。
<?php
// 使用 http_response_code() 设置状态码
// 更简洁,更容易理解
http_response_code(404);
// 使用 header() 函数设置状态码(传统方法)
// 需要指定完整的HTTP版本和状态消息
header("HTTP/1.1 404 Not Found");
// 两种方法的比较
echo "当前状态码(http_response_code): " . http_response_code() . "\n";
// 使用 header() 设置自定义状态消息
header("HTTP/1.1 418 I'm a teapot"); // RFC 2324
// 注意:http_response_code() 只接受数字状态码
// 它不能设置自定义状态消息
http_response_code(418); // 会设置状态码418,但消息可能是默认的
// 检查是否支持自定义状态消息
if (function_exists('header_register_callback')) {
// 在某些配置下,可以注册回调来修改状态消息
echo "支持自定义状态消息\n";
}
// 最佳实践:优先使用 http_response_code(),除非需要自定义状态消息
if ($custom_message_needed) {
header("HTTP/1.1 499 Custom Status Message");
} else {
http_response_code(499);
}
?>
在实际应用中进行错误处理和调试。
<?php
/**
* 安全地设置HTTP响应码
* @param int $code HTTP状态码
* @param string $message 可选的状态消息
* @return bool 成功返回true,失败返回false
*/
function safe_http_response_code($code, $message = null) {
// 检查状态码是否有效
if ($code < 100 || $code > 599) {
trigger_error("无效的HTTP状态码: $code", E_USER_WARNING);
return false;
}
// 检查头信息是否已经发送
if (headers_sent()) {
trigger_error("无法设置HTTP状态码,头信息已经发送", E_USER_WARNING);
return false;
}
// 如果有自定义消息,使用header()函数
if ($message !== null) {
$protocol = $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1';
header("$protocol $code $message");
} else {
// 否则使用http_response_code()
http_response_code($code);
}
return true;
}
/**
* 记录HTTP状态码变化
*/
class ResponseCodeLogger {
private static $history = [];
public static function set($code, $message = null) {
$previous = http_response_code();
if (safe_http_response_code($code, $message)) {
self::$history[] = [
'timestamp' => time(),
'previous' => $previous,
'new' => $code,
'message' => $message,
'backtrace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)
];
return true;
}
return false;
}
public static function getHistory() {
return self::$history;
}
public static function displayHistory() {
if (empty(self::$history)) {
echo "没有状态码变化记录\n";
return;
}
echo "<table border='1'>\n";
echo "<tr><th>时间</th><th>之前</th><th>之后</th><th>消息</th><th>位置</th></tr>\n";
foreach (self::$history as $entry) {
echo "<tr>\n";
echo "<td>" . date('Y-m-d H:i:s', $entry['timestamp']) . "</td>\n";
echo "<td>" . $entry['previous'] . "</td>\n";
echo "<td>" . $entry['new'] . "</td>\n";
echo "<td>" . htmlspecialchars($entry['message'] ?? '默认') . "</td>\n";
echo "<td>" . $entry['backtrace'][1]['file'] . ":" . $entry['backtrace'][1]['line'] . "</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
}
}
// 使用示例
ResponseCodeLogger::set(200);
ResponseCodeLogger::set(404, "Custom Not Found Message");
// 模拟一些状态码变化
try {
// 一些业务逻辑...
if (!file_exists('somefile.txt')) {
ResponseCodeLogger::set(404, "文件不存在");
}
// 更多的业务逻辑...
ResponseCodeLogger::set(200); // 成功
} catch (Exception $e) {
ResponseCodeLogger::set(500, "服务器错误: " . $e->getMessage());
}
// 显示历史记录
ResponseCodeLogger::displayHistory();
?>
http_response_code(),否则可能无法设置成功。true。http_response_code() 和 header() 都可以设置状态码,但 http_response_code() 更简洁。http_response_code() 不能设置自定义状态消息,而 header() 可以。header() 函数。| 问题 | 解决方案 |
|---|---|
| 状态码设置失败 | 检查是否在输出之后调用函数。使用 headers_sent() 函数检查头信息是否已经发送。 |
| 返回 false | 可能传递了无效的状态码,或者头信息已经发送。检查状态码是否在 100-599 范围内。 |
| 自定义状态消息 | 如果需要自定义状态消息,使用 header("HTTP/1.1 404 Custom Message") 而不是 http_response_code()。 |
| PHP 5.4 以下版本 | 使用 header() 函数替代,例如 header("HTTP/1.1 404 Not Found")。 |
| 状态码不生效 | 某些服务器配置可能会覆盖 PHP 设置的状态码。检查服务器配置(如 .htaccess、nginx 配置等)。 |
| 获取不到当前状态码 | 如果没有设置过状态码,http_response_code() 可能返回 false。确保在获取之前已经设置了状态码。 |