揭秘PHP伪协议:php://input 如何直接读取原始POST数据($ajax传输、curl传输、后端数据处理)
·
php://input 是 PHP 中的一个特殊流封装协议(stream wrapper),它允许读取原始的 POST 数据。这个流对于处理非表单数据(如 XML、JSON 等)的 HTTP POST 请求特别有用,因为它不依赖于 $_POST 或 $_FILES 超全局变量,后者通常用于处理表单数据(application/x-www-form-urlencoded 或 multipart/form-data 编码的表单)。
主要特点
- 原始数据:php://input 允许读取原始的 POST 数据,包括 HTTP 请求体中的原始数据。这对于需要直接处理 JSON、XML 或其他非表单格式的数据的 API 来说非常有用。
- 只读一次:需要注意的是,php://input 只能被读取一次。一旦它被读取,流中的指针就会到达末尾,后续的读取尝试将不会返回任何数据。因此,如果多次访问这些数据,应该在第一次读取时将其保存到某个变量中。
- 内容类型:尽管 php://input 可以用于读取任何类型的 POST 数据,但它最适合用于处理 Content-Type 不是 application/x-www-form-urlencoded 或 multipart/form-data 的请求。对于这些类型的数据,PHP 会自动填充 $_POST 和 $_FILES 超全局变量,因此通常不需要直接使用 php://input。
AJAX传输数据
$.ajax({
type: "POST",
url: "data.php",
data: JSON.stringify({
"name": "John Doe",
"age": 30,
"city": "New York"
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
console.log(response);
},
error: function (jqXHR, textStatus, errorThrown) {
console.error("AJAX 请求失败: " + textStatus + " - " + errorThrown);
// 尝试从响应文本中解析 JSON(尽管这通常不是必要的,因为 jQuery 已经尝试过了)
try {
var parsedResponse = JSON.parse(jqXHR.responseText);
console.error("尝试解析响应文本得到的 JSON:", parsedResponse);
} catch (e) {
console.error("解析响应文本为 JSON 时出错:", e);
}
}
});
CURL传输数据
当使用 cURL 来推送数据到服务器(比如 data.php),我们通常是在一个服务器端脚本或命令行工具中执行 cURL 命令。为了说明如何使用 cURL 推送 JSON 数据到 PHP 脚本,我们可以编写一个 PHP 脚本示例,该脚本使用 cURL 发送 POST 请求,并包含 JSON 格式的数据。
首先,这是 data.php 的一个简化版本,它接收 JSON 数据,解码它。
<?php
// 初始化 cURL 会话
$ch = curl_init();
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, 'http://yourdomain.com/data.php'); // 替换为你的 URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"name" => "John Doe",
"age" => 30,
"city" => "New York"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
// 执行 cURL 会话
$response = curl_exec($ch);
// 检查是否有错误发生
if(curl_errno($ch)){
echo 'Curl error: ' . curl_error($ch);
}
// 关闭 cURL 会话
curl_close($ch);
// 输出响应
echo $response;
?>
后端数据处理
// 设置内容类型为 JSON
header('Content-Type: application/json');
// 检查是否有 POST 请求且包含 JSON 数据
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SERVER['HTTP_CONTENT_TYPE']) && strpos($_SERVER['HTTP_CONTENT_TYPE'], 'application/json') !== false) {
// 读取原始 POST 数据
$json = file_get_contents('php://input');
// 尝试解码 JSON 数据
$data = json_decode($json, true); // 第二个参数为 true 时,将对象转换为关联数组
if (json_last_error() === JSON_ERROR_NONE) {
// 数据解码成功,现在将其保存到 data.json 文件中
$dataFilePath = 'data.json'; // 确保 PHP 脚本有权限写入此文件
file_put_contents($dataFilePath, json_encode($data, JSON_PRETTY_PRINT)); // 使用 JSON_PRETTY_PRINT 使输出更易读(可选)
// 返回成功响应
echo json_encode(['status' => 'success', 'message' => '数据已保存']);
} else {
// 数据解码失败
http_response_code(400); // 设置 HTTP 状态码为 400 Bad Request
echo json_encode(['status' => 'error', 'message' => '解析 JSON 数据失败']);
}
} else {
// 不是 POST 请求或未包含 JSON 内容类型
http_response_code(405); // 设置 HTTP 状态码为 405 Method Not Allowed
echo json_encode(['status' => 'error', 'message' => '请求方法不正确或未包含 JSON 内容类型']);
}
注意事项:
- 安全性:确保PHP 脚本对接收到的数据进行了适当的验证和清理,以防止安全漏洞(如 SQL注入、跨站脚本等)。在这个例子中,只是简单地将 JSON 数据解码并保存到文件中,没有进行任何额外的验证。
- 文件写入权限:确保PHP 脚本有权限写入 data.来json通知客户端文件请求所在的的结果目录.这在某些有助于服务器上客户端,.根据你可能响应需要进行适当的调整错误文件处理或。
- 错误处理:使用 HTTP 状态码和 JSON 响应 数据备份:在将新数据写入 data.json文件之前,考虑先备份旧文件,以防万一新数据有问题需要恢复。
- 并发写入:如果应用程序可能会同时从多个源接收数据,并尝试写入同一个data.json文件,那么你需要考虑并发写入的问题。在这种情况下,需要实现某种形式的锁定机制来避免数据损坏。
文章参考:
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)