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 内容类型']);
}

注意事项:

  1. 安全性:确保PHP 脚本对接收到的数据进行了适当的验证和清理,以防止安全漏洞(如 SQL注入、跨站脚本等)。在这个例子中,只是简单地将 JSON 数据解码并保存到文件中,没有进行任何额外的验证。
  2. 文件写入权限:确保PHP 脚本有权限写入 data.来json通知客户端文件请求所在的的结果目录.这在某些有助于服务器上客户端,.根据你可能响应需要进行适当的调整错误文件处理或。
  3. 错误处理:使用 HTTP 状态码和 JSON 响应 数据备份:在将新数据写入 data.json文件之前,考虑先备份旧文件,以防万一新数据有问题需要恢复。
  4. 并发写入:如果应用程序可能会同时从多个源接收数据,并尝试写入同一个data.json文件,那么你需要考虑并发写入的问题。在这种情况下,需要实现某种形式的锁定机制来避免数据损坏。

文章参考:

  1. PHP 伪协议:使用 php://input 访问原始 POST 数据
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐