使用cURL跨域POST数组报foreach()无效参数错误求助
问题分析与修复方案
核心错误原因
- 发送端构造请求时,错误地将原生PHP数组传给
CURLOPT_POSTFIELDS,而非编码后的JSON字符串;同时未设置Content-Type: application/json请求头,导致接收端无法正确解析JSON数据。 - 接收端未对
json_decode的结果做有效性校验,当解析失败时$data为null,直接执行foreach就会触发Invalid argument supplied for foreach()错误。
修复后的发送端脚本
<?php // 创建要传递的数组 $array_data = array ( array("name"=>"TestArr1","desc"=>"one","price"=>100), array("name"=>"TestArr2","desc"=>"two","price"=>200), array("name"=>"TestArr3","desc"=>"three","price"=>300) ); // 编码为JSON字符串 $json_data = json_encode($array_data); $ch = curl_init("https://www.receivingdomain.com/test_insert_multiple.php"); curl_setopt($ch, CURLOPT_POST, 1); // 传递JSON字符串而非原生数组 curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data); // 设置请求头告知接收端数据格式为JSON curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); // 添加CURL错误排查逻辑 if(curl_errno($ch)){ echo 'CURL错误: ' . curl_error($ch); } curl_close($ch); var_dump($response); $data = json_decode($response, true); ?>
修复后的接收端脚本(增加错误校验)
<?php // 获取原始POST数据 $jsonData = file_get_contents('php://input'); // 解码JSON并校验结果 $data = json_decode($jsonData, true); // 检查解码是否成功且结果为数组 if(!is_array($data)){ echo json_encode(array("message" => "数据格式错误或为空")); exit; } require ("/home/test/cnct.php"); /* 插入数据(后续需替换为参数绑定避免SQL注入) */ foreach($data as $row) { $sql = "INSERT INTO `products` (`id`, `name`, `description`, `price`, `category_id`, `created`, `modified`) VALUES (NULL, '" . $row["name"] . "', '" . $row["desc"] . "', '" . $row["price"] . "', '2', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"; $stmt = $conn->prepare($sql); $stmt->execute(); } // 关闭连接 $stmt = null; $conn = null; echo json_encode(array("message" => "Products were created.")); ?>
重要优化提示
尽快完善PDO参数绑定,彻底规避SQL注入风险,示例写法如下(替换接收端foreach内的代码):
$sql = "INSERT INTO `products` (`name`, `description`, `price`, `category_id`, `created`, `modified`) VALUES (:name, :desc, :price, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"; $stmt = $conn->prepare($sql); $stmt->bindParam(':name', $row["name"]); $stmt->bindParam(':desc', $row["desc"]); $stmt->bindParam(':price', $row["price"]); $stmt->execute();
内容的提问来源于stack exchange,提问作者CarpKing
相关产品推荐
相关产品推荐

