php大文件上传需修改php.ini中upload_max_filesize、post_max_size等参数并重启服务,前端分片通过http header传递元数据,php接收后校验分片完整性并加锁合并。

PHP默认上传限制在哪改
PHP处理大文件上传失败,八成卡在upload_max_filesize或post_max_size这两个配置上。它们不是前端限制,也不是Nginx/Apache限制,而是PHP解析请求体前就拦下的硬门槛。
修改位置在php.ini,不是.htaccess或ini_set()——后者对这两个参数完全无效:
-
upload_max_filesize = 200M(单个文件上限) -
post_max_size = 200M(整个POST请求体上限,必须≥前者) -
max_execution_time = 300(上传耗时长时需调高) -
max_input_time = 300(PHP读取输入的超时,同样关键)
改完必须重启PHP-FPM或Apache,用phpinfo()确认生效。别信“改了就能传2GB”——Web服务器(如Nginx)还有client_max_body_size要同步调大,否则请求根本到不了PHP层。
前端分片上传怎么和PHP后端对接
分片不是PHP自己做的,是前端把文件切块(比如每块5MB),逐个发POST请求,PHP只负责接收、校验、暂存、合并。关键在于前后端约定好分片元数据传递方式。
推荐用HTTP Header传分片信息,比塞在POST body里更干净:
- 前端发每个分片时带
X-Upload-ID: abc123(本次上传唯一ID) - 带
X-Chunk-Index: 0(当前是第几块,从0开始) - 带
X-Total-Chunks: 12(总块数) - PHP后端用
$_SERVER['HTTP_X_UPLOAD_ID']等读取,不依赖$_POST
服务端收到后,按upload_id + chunk_index命名临时文件(如abc123_0.tmp),存在可写目录(别放tmp下,避免被清理)。注意检查$_FILES['file']['error'] === UPLOAD_ERR_OK,否则可能是Nginx截断或客户端中断。
PHP怎么安全合并分片并校验完整性
所有分片收齐≠文件正确。常见坑是:某块上传失败但前端没报错、网络导致内容损坏、并发写入冲突。不能直接fopen(..., 'a')追加——多进程/多线程下会乱序或覆盖。
合并前必须做三件事:
- 用
scandir()扫描abc123_*.tmp,确认文件数等于X-Total-Chunks - 对每个分片计算
sha1_file()或md5_file(),和前端传来的X-Chunk-Hash比对(前端应在切片时预计算) - 用
flock()锁定合并目标文件,防止多个上传ID同时触发合并
合并示例(简化):
$final = fopen("uploads/abc123.final", "w");
for ($i = 0; $i
<p>完成后删掉所有<code>.tmp</code>文件。别忘了设好<code>chmod</code>权限,避免上传目录被Web直接访问。</p>
<h3>断点续传靠什么实现,PHP要做什么</h3>
<p>断点续传本质是“前端记住已传哪些块,失败后跳过重传”。PHP本身不维护状态,它只响应“这个块我有没有”——所以需要一个轻量存储来查。</p>
<p>最简方案:用文件存已接收的块索引(比数据库快,无连接开销):</p>
- 前端请求
GET /upload/status?upload_id=abc123 - PHP读
status/abc123.json,返回{"uploaded":[0,1,3,4]} - 前端对比
X-Total-Chunks,只重传缺失的索引 - 每次成功接收分片后,用
file_put_contents(..., JSON_UNESCAPED_UNICODE | LOCK_EX)更新该文件
注意:JSON写入必须加LOCK_EX,否则并发上传同一ID时会丢块。如果上传ID生命周期长(比如几天),得加定时清理逻辑,不然磁盘会被.json和.tmp占满。
真正的难点不在PHP代码多复杂,而在于前端如何可靠判断“这一块到底传没传成功”,以及网络抖动时如何避免重复写同一块——这要求每个分片带服务端可验证的唯一标识(如hash+index组合),而不是依赖HTTP状态码简单判断。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











