本文目录导读:

- 使用
php://input流(最常用) - 使用
$HTTP_RAW_POST_DATA(PHP 5.6 之前) - 使用
php://input的注意事项 - 完整的请求体获取函数
- 处理不同 HTTP 方法的请求
- 使用 cURL 测试 API
- 最佳实践建议
在 PHP 中获取原始请求体有多种方法,以下是主要的几种方式:
使用 php://input 流(最常用)
<?php
// 获取原始请求体
$rawBody = file_get_contents('php://input');
// 如果是 JSON 数据,可以解码
$data = json_decode($rawBody, true);
// 输出原始数据
echo $rawBody;
?>
使用 $HTTP_RAW_POST_DATA(PHP 5.6 之前)
<?php // 注意:此方法在 PHP 5.6+ 已废弃,PHP 7.0+ 已移除 // 需要在 php.ini 中启用 always_populate_raw_post_data global $HTTP_RAW_POST_DATA; $rawBody = $HTTP_RAW_POST_DATA; ?>
使用 php://input 的注意事项
<?php
// 检查请求内容类型
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
// 获取原始请求体
$rawBody = file_get_contents('php://input');
类型处理
switch ($contentType) {
case 'application/json':
$data = json_decode($rawBody, true);
break;
case 'application/x-www-form-urlencoded':
parse_str($rawBody, $data);
break;
case 'multipart/form-data':
// 文件上传时,php://input 不适用于 multipart/form-data
// 使用 $_FILES 和 $_POST
break;
default:
// 其他类型
$data = $rawBody;
}
?>
完整的请求体获取函数
<?php
function getRequestBody() {
$rawBody = '';
// 获取原始请求体
$rawBody = file_get_contents('php://input');
// 如果没有获取到,尝试其他方式
if (empty($rawBody)) {
// 检查是否已填充到全局变量
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
$rawBody = $GLOBALS['HTTP_RAW_POST_DATA'];
}
}
return $rawBody;
}
// 使用示例
$body = getRequestBody();
echo "原始请求体: " . $body;
// 解析 JSON
if (!empty($body)) {
$jsonData = json_decode($body, true);
if (json_last_error() === JSON_ERROR_NONE) {
print_r($jsonData);
}
}
?>
处理不同 HTTP 方法的请求
<?php
// 获取请求方法
$method = $_SERVER['REQUEST_METHOD'];
// 根据请求方法获取数据
switch ($method) {
case 'POST':
// 检查内容类型
if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
// JSON 数据
$data = json_decode(file_get_contents('php://input'), true);
} elseif (strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false) {
// 文件上传,使用 $_POST 和 $_FILES
$data = $_POST;
} else {
// 其他类型的 POST 数据
$data = $_POST;
if (empty($data)) {
$data = json_decode(file_get_contents('php://input'), true);
}
}
break;
case 'PUT':
case 'PATCH':
// PUT/PATCH 请求通常使用原始请求体
$data = json_decode(file_get_contents('php://input'), true);
break;
case 'DELETE':
// DELETE 请求
$data = json_decode(file_get_contents('php://input'), true);
break;
default:
// GET 请求
$data = $_GET;
}
// 输出结果
echo "请求方法: " . $method . "\n";
echo "请求数据: ";
print_r($data);
?>
使用 cURL 测试 API
<?php
// 发送 POST 请求测试
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/api');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"key":"value"}');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
最佳实践建议
- 优先使用
php://input,它是官方推荐的方式 - 处理前检查请求大小,避免内存问题
- 根据 Content-Type 进行相应解析
- 对于 JSON 数据,使用
json_decode时注意错误处理
<?php
// 推荐的完整处理方式
function processRequest() {
// 检查请求大小
$maxSize = 10 * 1024 * 1024; // 10MB
$contentLength = $_SERVER['CONTENT_LENGTH'] ?? 0;
if ($contentLength > $maxSize) {
http_response_code(413);
echo json_encode(['error' => '请求体太大']);
return;
}
// 获取原始请求体
$rawBody = file_get_contents('php://input');
// 解析数据
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') !== false) {
$data = json_decode($rawBody, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(['error' => '无效的 JSON 数据']);
return;
}
} else {
$data = $rawBody;
}
return $data;
}
// 使用
$requestData = processRequest();
?>
选择哪种方法取决于你的 PHP 版本和具体需求。php://input 是所有 PHP 版本都支持且推荐的方式。