php处理请求和响应的核心在于严格遵循http协议:curl_init是可靠起点,需显式配置跳转、ssl和json头;$_post为空时应读php://input并判断content-type;options预检须在入口首行拦截并返回204;状态码必须与header配合且重定向后exit。

PHP里处理请求和响应,不是“会用$_GET和$_POST”就完事了——真正卡住人的,是重定向不跳、JSON收不到、OPTIONS被405、状态码不生效、HTTPS报错这些具体问题。核心就一条:别把HTTP当黑盒,每个环节都得对得上协议。
curl_init才是发请求的唯一靠谱起点
很多人用file_get_contents拼stream_context_create发POST,结果302不跳、Cookie不带、HTTPS证书直接报错返回false。它底层根本不支持自动跳转、会话维持或完整SSL握手。
-
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1)必须开,否则302响应体为空,连Location头都懒得跟 - 发POST时,
CURLOPT_POST必须显式设为1,光传CURLOPT_POSTFIELDS没用 - 传JSON要两步:设
CURLOPT_HTTPHEADER含"Content-Type: application/json",且CURLOPT_POSTFIELDS必须是json_encode($data)后的字符串 - 开发环境调HTTPS,加
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0)和curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);生产环境必须配好CA证书,不能关验证
$_POST为空?先看Content-Type再读php://input
$_POST只解析application/x-www-form-urlencoded和multipart/form-data两类请求体。前端用fetch发application/json,$_POST永远是空数组——这不是bug,是设计。
- 用
curl -H "Content-Type: application/json" -d '{"a":1}' http://your-api测试,$_POST一定为空,但file_get_contents('php://input')能拿到原始JSON - 正确做法:先判断
strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false,再读php://input并json_decode(..., true) - 注意:
php://input只能读一次,且在$_POST已触发解析(如multipart)后会为空
OPTIONS预检请求必须在入口文件最开头拦截
Apache/Nginx默认把OPTIONS拦在PHP外,直接返回405——你写的if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS')根本不会执行。
- Apache需加
RewriteCond %{REQUEST_METHOD} OPTIONS+RewriteRule ^(.*)$ index.php [QSA,L] - Nginx建议在
location块里用if ($request_method = 'OPTIONS')直接返回204,不进PHP - 若走PHP处理,必须在
index.php第一行判断:if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS'),然后立刻header()发CORS头 +http_response_code(204)+exit -
Access-Control-Allow-Origin写*时,Access-Control-Allow-Credentials必须为false;要带Cookie就得写明确域名,二者不可共存
状态码不生效?http_response_code和header得配对用
只echo json_encode(['error' => 'not found']),却不设状态码,前端fetch().ok永远是true——因为PHP默认返回200,哪怕逻辑出错了。
-
http_response_code(404)只改响应行数字,某些Nginx配置下会被覆盖回200;稳妥写法是http_response_code(404); header('Content-Type: application/json'); - 500类错误别在
try/catch里硬设200,应让未捕获异常触发PHP原生500,或显式http_response_code(500) - 重定向必须用
header('Location: /login')+exit,否则后续代码仍会执行
最难缠的从来不是语法,而是那些“看起来该有值却为空”“明明写了头却不生效”“本地OK上线就跨域失败”的细节——它们全藏在HTTP协议与PHP运行机制的交界处,绕不开,也假装不了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











