Python正常PHP报错,如何实现PHP向自制Flask API发数据?
嘿,我来帮你搞定PHP调用Flask API失败的问题!既然Python端能正常发送数据,说明你的Flask API本身是没问题的,问题大概率出在PHP这边的请求配置和Python端不一致上。我把常见的坑和对应的解决方法列出来,你可以逐一排查:
Flask默认只会解析带有Content-Type: application/json头的JSON数据,很多PHP开发者容易忽略这个点——比如用curl发送请求时没设置这个头,或者直接传了表单格式的数据,这时候Flask就会因为无法解析请求体而报错。
你回忆下Python端的请求,是不是用了json.dumps()把数据转成JSON字符串,同时设置了headers={'Content-Type': 'application/json'}?那PHP这边也要对应起来:
- 如果用curl,一定要加上这行:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); - 如果用
file_get_contents,要在上下文里配置请求头:$context = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => json_encode($data) ] ]); $response = file_get_contents($url, false, $context);
Python发送的是标准的JSON字符串,但PHP里如果直接传数组或者用http_build_query()生成的表单字符串,Flask肯定解析不了。你必须用json_encode()把PHP数组转换成JSON格式的字符串再发送。
❌ 错误示例(直接传数组,会自动转成表单格式):
$data = array('key' => 'value'); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
✅ 正确示例(转成JSON字符串):
$data = json_encode(array('key' => 'value')); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
你要确认Flask API的路由是用哪种请求方法定义的,比如@app.route('/api/data', methods=['POST'])或者methods=['PUT']。PHP里必须使用对应的请求方法:
- 如果是POST请求,设置
curl_setopt($ch, CURLOPT_POST, true); - 如果是PUT/DELETE等其他方法,要用
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');(把PUT换成对应的方法)
如果请求方法不匹配,Flask会返回405 Method Not Allowed错误,你可以在PHP里捕获响应状态码来确认:
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo 'HTTP状态码: ' . $httpCode;
如果你的Flask API是HTTPS协议,PHP curl默认会验证SSL证书。如果是本地开发用的自签证书,这时候会出现证书验证失败的错误。开发环境可以临时关闭验证(生产环境不建议,最好配置合法的CA证书):
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
如果上面的方法都没解决,建议你在PHP里捕获curl的错误信息,或者查看Flask的详细日志:
$response = curl_exec($ch); if(curl_errno($ch)){ echo 'Curl错误信息: ' . curl_error($ch); } // 同时打印HTTP状态码 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo 'HTTP状态码: ' . $httpCode;
比如400 Bad Request一般是数据格式不对,401 Unauthorized是权限问题,根据具体错误再针对性解决。
最后给你一个完整的PHP请求示例,你可以直接参考:
<?php // 替换成你的Flask API地址 $apiUrl = 'http://localhost:5000/api/data'; // 要发送的数据 $postData = array( 'username' => 'test_user', 'content' => '来自PHP的测试数据' ); // 初始化curl $ch = curl_init($apiUrl); // 配置curl参数 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 开发环境HTTPS临时关闭证书验证(可选) // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 执行请求并获取响应 $response = curl_exec($ch); // 检查错误 if(curl_errno($ch)){ echo '请求失败: ' . curl_error($ch); } else { $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo 'HTTP状态码: ' . $httpCode . '<br>'; echo 'API响应: ' . $response; } // 关闭curl curl_close($ch); ?>
内容的提问来源于stack exchange,提问作者egorkh

