PHP后端开发卡点在于环境配置、请求生命周期、数据流转及常见陷阱的综合作用:Web服务器与PHP解释器分工不清导致本地服务异常;不同Content-Type决定$_POST或php://input的使用;PDO预处理防注入需全程参数绑定;JSON输出乱码源于header时机与BOM问题;排查500错误须优先分析日志而非代码。
PHP 后端开发不是“学完语法就能写接口”,真正卡住人的,是环境、请求生命周期、数据流转和常见陷阱的组合问题。
php -v 有但 localhost 打不开?绝大多数新手第一关就栽在环境上——不是 PHP 没装好,而是没搞清“Web 服务器”和“PHP 解释器”的分工。
php -v 只说明 CLI 模式能跑,不代表 Web 服务可用php -S localhost:8000 跑内置服务器时,必须手动指定路由器文件(如 router.php),否则静态资源 404phpinfo() 输出比 php -v 更可靠php@8.2 需手动软链到 /usr/local/bin/php,否则 Apache 加载不到模块$_POST 和 file_get_contents('php://
input') 到底该用哪个?这取决于前端发的是什么格式。PHP 不会自动解析非 application/x-www-form-urlencoded 或 multipart/form-data 的请求体。
fetch('/api', { method: 'POST', body: JSON.stringify({a:1}) }) → Content-Type 是 application/json → $_POST 为空,必须用 file_get_contents('php://input') 读原始流FormData → Content-Type 是 multipart/form-data → $_POST 和 $_FILES 自动填充,php://input 为空(已被读取)php://input 只能读一次,且不能用于 enctype="multipart/form-data" 场景预处理防注入的前提是:所有动态值都走参数绑定。任何字符串拼接、变量插值、表名/字段名代入,都会让预处理失效。
$stmt = $pdo->prepare("SELECT * FROM {$table} WHERE id = ?") —— $table 是拼进去的,完全绕过预处理in_array($table, ['users', 'posts'], true),再拼接PDO::PARAM_STR 强制类型——它不校验内容,只影响 PDO 内部处理方式;真正防注入靠的是占位符隔离,不是类型声明PDO::ATTR_EMULATE_PREPARES => false,避免 MySQL 在客户端模拟预处理(某些旧版本下会退化为字符串拼接)\uXXXX 或乱码?根本原因不是编码设置错了,而是输出前没清理缓冲区或 header 写晚了。
echo json_encode(...) 前调用 header('Content-Type: application/json; charset=utf-8'),且不能有任何输出(包括空格、BOM、echo "")hexdump -C yourfile.php | head 查看开头是否为 ef bb bf
json_encode() 默认不转义中文,如果看到 \u6709,大概率是用了 JSON_UNESCAPED_UNICODE 以外的选项,或框架自动封装了一层var_dump(headers_sent()) 确认 header 是否已发送真实项目里最耗时间的,往往不是写逻辑,而是判断“当前这个 500 错误,到底是 Nginx 配置、PHP-FPM 超时、还是 MySQL 连接池满了”。先盯住 error_log 和 access_log,再动代码。