Yii框架上传临时文件默认存于系统临时目录(如Linux的/tmp),PHP自身写入且Yii不自动清理,需显式unlink或定时兜底清理,否则易致磁盘满、敏感泄露或上传失败。

Yii框架上传文件时生成的临时文件默认存于系统临时目录(如Linux的/tmp),但框架本身不自动清理这些文件,残留会导致磁盘满、敏感信息泄露或后续上传失败。
临时文件实际存放位置
Yii 通过 $_FILES 接收上传时,PHP 自身会将文件先写入系统临时目录,路径由 sys_get_temp_dir() 返回,与 Yii 配置无关:
– Linux/macOS 下通常是 /tmp;
– Windows 下为 C:\Users\XXX\AppData\Local\Temp\;
– Docker 或宝塔环境可能被重定向至容器内指定路径(如 /var/tmp),需运行 php -r "echo sys_get_temp_dir();" 确认真实路径。
为什么 UploadedFile::getInstance() 后临时文件还在
调用 UploadedFile::getInstance('file') 只是封装了 $_FILES['file'] 的元数据,并未触发任何删除逻辑;
临时文件是否被删,取决于 PHP 的生命周期管理:只有请求完全结束、且该 UploadedFile 对象未被引用时,PHP 才可能在 GC 阶段清理——【这不可靠,不能依赖】;
一旦你在控制器中调用了 $file->saveAs() 或 $file->getStream(),临时文件很可能已被移动或读取,但原始路径上的文件残留风险依然存在——尤其是上传中断、验证失败或异常退出时。
手动清理临时文件的两种安全方式
方法一:在模型 upload() 方法末尾显式 unlink
在 upload() 成功保存后,立即执行 unlink($file->tempName):
public function upload() {<br> if ($this->validate()) {<br> $path = 'uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension;<br> if ($this->imageFile->saveAs($path)) {<br> @unlink($this->imageFile->tempName); // 主动清除临时文件<br> return true;<br> }<br> }<br> return false;<br>}注意:必须放在 saveAs() 成功之后,否则会删掉还没保存的原始临时文件。
方法二:统一兜底清理(推荐用于高并发或失败率高的场景)
在控制台命令中封装定时清理逻辑,例如创建 app\commands\UploadTempCleanController:
① 获取当前 PHP 临时目录:$tempDir = sys_get_temp_dir();
② 构造匹配 XML/上传类临时文件的 glob 模式:$pattern = $tempDir . '/php*';(PHP 默认临时文件前缀为 php)
③ 仅删除 1 小时内未访问、且文件名含 php 前缀的文件:find $tempDir -name "php*" -mmin +60 -delete,避免误删正在使用的会话或日志文件。
生产环境必须加的防护措施
在 Web 服务器层限制上传临时文件生命周期:
Nginx 配置中添加 client_body_temp_path /var/tmp/nginx-client-body 1 2 2;,并确保 /var/tmp 有独立磁盘配额;
Linux 系统启用 systemd-tmpfiles 并自定义规则,例如在 /etc/tmpfiles.d/yii.conf 中写入:L /tmp/yii-upload - - - 1h,强制 1 小时后自动清理;
【切勿依赖 PHP 或 Yii 自动清理,所有上传入口都必须做显式 unlink 或外部兜底】。


















