thinkphp 6.0文件上传必须使用filesystem抽象层并服务端真实校验:单图用putfile自动重命名分目录存储,多图需遍历处理且禁用原始文件名,须validate精准校验mime与大小,缩略图加水印需用think-image扩展,高安全场景应上传至非web目录并通过nginx alias映射url。

在ThinkPHP 6.0项目中快速实现安全、可维护的文件上传与图片处理,必须避开直接调用$file->move()这类裸操作,否则极易触发路径遍历、MIME伪造、远程代码执行等高危问题;需严格依赖Filesystem抽象层并配合服务端真实校验。
单图上传并自动重命名存储
这是最常用的基础场景,适用于头像、封面图等单文件提交。
第一步:在控制器中获取上传文件对象,使用Request::file('image'),注意字段名必须与前端input的name属性完全一致。
第二步:调用Filesystem::disk('public')->putFile('avatars', $file),该方法会自动完成真实MIME校验、md5+uniqid重命名、按日期分目录(如avatars/72/)写入storage/app/public/下,返回相对路径如avatars/72/ef580909368d824e899f77c7c98388.jpg。
第三步:拼接可访问URL,先调用Filesystem::getDiskConfig('public', 'url')获取配置中的url前缀(默认为/storage),再拼接路径,【注意:必须用str_replace('\', '/', $savename)统一斜杠,否则Windows路径在Nginx下会404】。
第四步:部署后务必执行php think storage:link命令,否则/storage/路径无法被Web服务器解析。
多图上传并批量入库
适用于商品相册、案例图集等需要一次提交多张图片的业务。
方法一:前端使用name="photos[]",后端用Request::file('photos')获取数组对象列表,遍历每个$file执行putFile()。
方法二:更高效的方式是用Filesystem::disk('public')->putFileAs()配合foreach,显式指定子目录和文件名规则,避免putFile()默认的哈希分片导致路径不可控。
上传成功后,将每张图的相对路径存入数据库对应字段(如JSON数组或关联表),【严禁把原始$_FILES['photos']['name']直接入库,必须丢弃全部原始文件名】。
限制大小+精准MIME校验上传
仅靠后缀校验(ext)极不安全,攻击者可上传.php文件并改名为1.jpg绕过;必须校验真实MIME类型。
调用链式validate()方法,传入['size' => 5242880, 'mime' => 'image/jpeg,image/png,image/gif'],其中size单位为字节,mime值必须与$_FILES['xxx']['type']实际返回值严格匹配,不是浏览器伪造的后缀。
如果校验失败,框架自动抛出ValidateException异常,catch后返回json错误提示即可,无需手动判断。
上传后生成缩略图并加水印
需先安装扩展:composer require topthink/think-image。
上传成功获得真实文件路径后,用Image::open($realPath)加载图片,调用thumb(200, 200, hinkimageImage::THUMB_CENTER)生成居中裁剪缩略图,再用water($waterImg, hinkimageImage::WATER_SOUTHEAST)添加右下角水印。
缩略图保存路径建议独立于原图,例如在public/thumbs/下,避免混淆;保存时同样要用putFile()而非直接file_put_contents(),确保路径安全和存储驱动兼容性。
安全上传到非Web目录并映射URL
最高等级的安全实践:绝不允许用户上传文件落在public/可直接访问路径下,防止.htaccess失效或Nginx配置疏漏导致PHP脚本被执行。
创建runtime/upload/目录,设置权限为0755,确保Web进程可写但不可执行。
上传时用Filesystem::disk('local')->putFile('upload', $file),其中'disk'需在config/filesystem.php中预定义local驱动,root指向runtime/upload/。
然后在Nginx配置中添加alias /uploads/ /path/to/your/project/runtime/upload/;,使/uploads/202405/12/abc.jpg可被访问,而真实路径对前端完全隐藏。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











