这个坑值得记一笔。CentOS 7.9 的 PHP 把 upload_tmp_dir 指到了 /data/tmp,挂载参数里带 noexec,用户上传图片全部失败,PHP 错误日志只有一句 unable to move uploaded file。
刚开始盯着「open_basedir 没包含新的临时目录,is_uploaded_file 直接返回假」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。noexec 挂载禁止执行,PHP 在处理上传临时文件时被判为不可用;目录属主是 root,php-fpm 的 www 用户没有写权限;tmp 目录所在分区 inode 用尽,创建临时文件失败。
动手时先确认目录所在分区的挂载参数
findmnt -T /data/tmp -o TARGET,OPTIONS
接着换到不带 noexec 的目录并给对属主
mkdir -p /var/lib/php/upload && chown www:www /var/lib/php/upload
然后改 php.ini 并同步 open_basedir
sed -i 's#^upload_tmp_dir.*#upload_tmp_dir = /var/lib/php/upload#' /etc/php.ini
末了重启 FPM 后传一张图验证
systemctl restart php-fpm && php -i | grep upload_tmp_dir
改完先别撤,确认这几项。上传接口返回成功,目标目录能看到落地的图片,php -i 里的 upload_tmp_dir 指向新路径,错误日志不再出现 move 失败。
noexec 只是禁止执行,不应该影响普通读写,但 PHP 的上传校验会碰这个限制;换目录比改挂载参数安全,后者会影响整个分区。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
