PHP curl发送POST数据写入文件时接收端获取空数组如何解决
问题背景
编写简易PHP代码通过curl发送POST数据,将接收端获取的数据写入文件时始终得到空值。数据在两个域名间跨域传输,多次参考示例调整代码仍无法正常获取参数。
原有代码
curl发送端函数
function run() { $serverData['php'] = PHP_VERSION; $serverData['url'] = $_SERVER['SERVER_NAME']; $ch = curl_init('https://test.com/tracking/'); curl_setopt ($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $serverData); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); }
接收端POST处理逻辑
$response = $_POST['url']." ".$_POST['php']; $fp = fopen('vardump.txt', 'w'); fwrite($fp, serialize($response)); fclose($fp); var_dump($response);
故障核心原因
- 开启
CURLOPT_FOLLOWLOCATION后,curl默认行为是遇到30x跳转时,自动将POST请求转换为GET请求,携带的POST参数会在跳转过程中直接丢弃。目标地址如果存在目录自动补全斜杠、HTTP强制跳HTTPS、域名重定向等规则,就会触发该问题。 - 未配置HTTPS请求相关参数,部分PHP环境下默认开启严格证书校验,请求目标HTTPS站点时会直接校验失败,请求根本没有送达接收端。
- 未设置请求返回配置和错误捕获,发送端出现请求失败时没有任何日志,无法定位问题。
- 接收端未做参数存在性校验,参数丢失时直接访问数组键会触发Notice级错误,写入文件的内容为空。
修复方案
发送端代码调整
function run() { $serverData['php'] = PHP_VERSION; $serverData['url'] = $_SERVER['SERVER_NAME']; $ch = curl_init('https://test.com/tracking/'); curl_setopt($ch, CURLOPT_POST, true); // 将数组转为标准表单编码格式,兼容性更强 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($serverData)); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 强制跳转时保留POST请求方法,避免参数丢失 curl_setopt($ch, CURLOPT_POSTREDIR, 3); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HEADER, 0); // 配置HTTPS请求,生产环境可替换为指定CA证书路径提升安全性 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 开启响应返回,设置超时时间 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 声明表单格式请求头,保证服务端正常解析参数 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/x-www-form-urlencoded' ]); $result = curl_exec($ch); // 记录请求错误方便排查 if (curl_errno($ch)) { file_put_contents(__DIR__.'/curl_error.log', curl_error($ch), FILE_APPEND); } curl_close($ch); }
接收端代码调整
// 增加参数存在性判断,避免报错 $url = isset($_POST['url']) ? trim($_POST['url']) : ''; $phpVersion = isset($_POST['php']) ? trim($_POST['php']) : ''; $response = $url." ".$phpVersion; $fp = fopen('vardump.txt', 'w'); // 同时写入原始POST报文,方便定位参数解析问题 $logContent = "原始请求流:".file_get_contents('php://input')."\n解析结果:".serialize($response); fwrite($fp, $logContent); fclose($fp); var_dump($response);
额外排查项
- 确认接收端地址不存在额外重定向规则,若存在重定向必须保留POST请求方法。
- 确认接收站点的WAF、访问控制规则没有拦截来源请求,拦截状态下无法正常接收参数。
- 若需要传输JSON格式数据,需将请求头
Content-Type改为application/json,接收端不能直接通过$_POST取参,需解析php://input原始请求流获取数据。
内容的提问来源于stack exchange,提问作者Mārcis
相关产品推荐
相关产品推荐

