Ubuntu环境下PHP调用exec执行wget无法完整下载大文件
解决PHP exec调用wget下载大文件不完整的问题
我之前处理过类似的场景,咱们一步步拆解可能的原因和对应的解决办法:
1. 先检查wget的参数是否搞混了
这是最容易踩的坑!你在代码里用的是-o(小写字母o),但这个参数是把wget的日志输出写入指定文件,而不是保存下载的文件本身!真正用来指定下载文件保存路径的是-O(大写字母O)。
你说直接在shell里执行能完整下载,是不是你shell里实际用的是大写O?如果PHP脚本里写错成小写o,那你看到的345MB文件其实是wget的日志,而真正的下载文件可能在PHP的工作目录里(比如网站根目录),但因为脚本没指定正确的输出路径,可能后续被忽略或者覆盖了。
修正后的PHP代码应该是:
exec('wget -O '.$local.' '.$url);
如果需要同时记录日志,可以再加一个-o参数指定日志文件:
exec('wget -O '.$local.' -o /var/log/wget_download.log '.$url);
2. 排查PHP执行环境的超时限制
虽然你说php.ini里没发现限制,但还有几个地方可能影响:
- 脚本级超时:如果你的PHP脚本里没有设置
set_time_limit(0);,即便php.ini的max_execution_time设得很高,脚本也可能因为超时被终止。2GB的文件按40MB/s算需要约50秒,所以要确保脚本不会中途超时,在exec调用前加上:set_time_limit(0); // 取消脚本执行时间限制 - php-fpm的进程超时:如果用的是php-fpm,还要检查
php-fpm.conf或者对应的www.conf里的request_terminate_timeout参数,这个是强制终止请求的超时时间,默认可能是30秒或者几分钟,需要调大或者设为0(不限制)。
3. 检查系统对PHP进程的资源限制
PHP运行的用户(比如www-data)可能被系统的ulimit限制了资源,比如最大文件大小、内存使用等:
- 可以先切换到www-data用户,执行
ulimit -a查看当前限制,重点看file size(最大文件大小)、virtual memory(虚拟内存)、max memory size(最大内存)这些项,如果有小于2GB的限制,需要修改。 - 如果是systemd管理的php-fpm服务,还可以在
php-fpm.service文件里添加LimitFSIZE=infinity之类的配置,解除文件大小限制,然后重启php-fpm服务。
4. 确认wget在PHP环境中的行为差异
PHP执行exec时的环境变量和你登录shell时不一样,可能导致wget使用不同的配置:
- 可以在exec里指定wget的完整路径(比如
/usr/bin/wget),避免调用到不同版本的wget。 - 可以加上
--no-config参数,让wget不读取任何配置文件,强制使用默认行为:exec('/usr/bin/wget --no-config -O '.$local.' '.$url);
5. 换用更可靠的PHP原生下载方式(备选方案)
如果wget的方式始终有问题,也可以直接用PHP的原生函数来下载,比如用curl:
set_time_limit(0); $url = 'http://xxxx/xxx.zip'; $local = '/filepath/xxx.zip'; $ch = curl_init($url); $fp = fopen($local, 'wb'); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_TIMEOUT, 0); // 取消curl超时限制 curl_exec($ch); curl_close($ch); fclose($fp);
这种方式可以更好地控制下载过程,也避免了依赖系统的wget命令。
内容的提问来源于stack exchange,提问作者cdmalcl
相关产品推荐
相关产品推荐

