post_max_size 是 PHP 导入大 SQL 文件失败的首要原因,其默认值通常仅 8M,需设为略大于 SQL 文件大小并同步调整 memory_limit 和 Nginx 的 client_max_body_size;更稳妥的方式是绕过 POST,改用命令行 mysql 工具导入。
PHP 导入大 SQL 文件失败:post_max_size 是第一道关卡
导入几百 mb 的 sql 文件时卡在“空白页”或直接 500,大概率不是 mysql 的问题,而是 php 在接收请求体阶段就截断了——post_max_size 默认通常只有 8m,远小于你的 .sql 文件大小。
它和 upload_max_filesize 不同:post_max_size 控制整个 POST 请求体上限(含表单字段、文件内容、边界分隔符),哪怕你用 file_get_contents($_FILES['sql']['tmp_name']) 读取,上传阶段已失败,$_FILES 根本不会被填充。
-
post_max_size必须 ≥ 实际 POST 数据总大小(SQL 文件 + 其他表单字段) - 它不能大于
memory_limit,否则 PHP 解析 POST 时会因内存不足崩溃 - 修改后必须重启 PHP-FPM 或 Apache,仅 reload 不生效
如何安全调高 post_max_size 而不引发其他问题
盲目设成 2G 看似一劳永逸,但会放大 DoS 风险,且可能触发 Nginx 的 client_max_body_size 拦截(它默认是 1M)。
- 先确认当前值:
php -i | grep post_max_size或查phpinfo() - 推荐设置为略大于目标 SQL 文件(比如 512M 文件 → 设
post_max_size = 512M) - 同步检查并调整
memory_limit(至少设为512M或更高) - 如果用 Nginx,必须加
client_max_body_size 512M;到 server 或 location 块,否则请求根本到不了 PHP
导入大 SQL 更稳的替代方案:绕过 POST,改用命令行或流式读取
即使调高了 post_max_size,浏览器上传仍不可靠:超时、网络抖动、无进度反馈。生产环境应避免走 Web 表单上传大 SQL。
- 把 SQL 文件放服务器本地,用
mysql -u user -p database 直接执行 - 若必须 Web 触发,改用 PHP 的
fopen()+fgets()分块读取本地文件,逐段mysqli::multi_query()执行(注意语句分割逻辑) - 禁用
set_time_limit(0)和ignore_user_abort(true),防止用户关闭页面中断执行
验证是否真由 post_max_size 导致失败
不要猜。PHP 在 POST 超限时行为隐蔽:$_POST 为空、$_FILES 为空、$_SERVER['CONTENT_LENGTH'] 可能显示原始大小,但实际只收到部分数据。
- 临时加一句日志:
error_log("POST size: " . $_SERVER['CONTENT_LENGTH']); - 检查 PHP 错误日志,搜索
PHP Warning: POST Content-Length of [X] bytes exceeds the limit - 用
curl -F "sql=@large.sql" http://yoursite/import.php测试,并加-v看响应头和状态码
真正麻烦的不是调参数,而是很多人改了 post_max_size 却忘了 Nginx 或没重启 PHP-FPM,然后反复试错。参数生效与否,日志里那条警告信息最诚实。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











