Become a sponsor

概述
文件上传配置定义在 config/file.php 和 .env 中,控制上传目录、域名、大小限制、允许的文件类型等。所有值通过 env() 函数从 .env 文件读取,支持多环境切换。
// config/file.php — 文件上传配置
// 所有值通过 env() 函数从 .env 文件读取,支持多环境切换
return [
'upload_dir' => env('file.upload_dir', ''), // 上传根目录(绝对路径)
'domain_url' => env('file.domain_url', ''), // 文件访问域名(拼接完整 URL 用)
'temp_dir' => 'temp', // 临时目录名(相对 upload_dir)
'image_ext' => env('file.image_ext', 'gif,jpg,jpeg,png,bmp,webp,svg'), // 允许的图片后缀
'file_ext' => env('file.file_ext', 'gif,jpg,jpeg,png,bmp,webp,svg,doc,docx,xls,xlsx,ppt,pptx,pdf,zip,rar,txt,csv,mp3,mp4,sql,js,css'), // 允许的文件后缀
'max_size' => env('file.max_size', 10) * 1024 * 1024, // 最大大小(MB → 字节)
];| 配置项 | .env 变量 | 默认值 | 说明 |
|---|---|---|---|
upload_dir | [FILE] UPLOAD_DIR | - | 上传根目录(绝对路径),所有文件存储于此 |
domain_url | [FILE] DOMAIN_URL | - | 文件访问域名,用于拼接完整 URL |
temp_dir | - | temp | 临时目录名(相对 upload_dir) |
image_ext | [FILE] IMAGE_EXT | gif,jpg,jpeg,png,bmp,webp,svg | 图片允许后缀 |
file_ext | [FILE] FILE_EXT | 多种后缀 | 文件允许后缀 |
max_size | [FILE] MAX_SIZE | 10 | 单文件最大大小(MB) |
; .env
[FILE]
UPLOAD_DIR = D:/uploads/rxthinkcmf要求:
各环境示例:
| 环境 | 路径示例 |
|---|---|
| Windows 开发 | D:/uploads/rxthinkcmf |
| Linux 开发 | /home/www/uploads/rxthinkcmf |
| Linux 生产 | /data/uploads/rxthinkcmf |
| Docker | /uploads/rxthinkcmf(挂载卷) |
; .env
[FILE]
DOMAIN_URL = https://cdn.example.com要求:
/ 结尾各环境示例:
| 环境 | 域名示例 |
|---|---|
| 本地开发 | (留空,使用相对路径) |
| 测试环境 | https://test-cdn.example.com |
| 生产环境 | https://cdn.example.com |
| 对象存储 | https://bucket-name.oss-cn-hangzhou.aliyuncs.com |
; .env
[FILE]
MAX_SIZE = 10单位: MB(配置文件中会自动转换为字节:10 * 1024 * 1024)
建议值:
| 场景 | 建议值 | 说明 |
|---|---|---|
| 头像上传 | 2 MB | 图片通常不会太大 |
| 文章封面 | 5 MB | 压缩后的图片 |
| 通用文件上传 | 10 MB | 默认值 |
| 文档上传 | 20 MB | PDF/Word 等 |
| 视频上传 | 100 MB | 需配合分片上传 |
; .env
[FILE]
IMAGE_EXT = gif,jpg,jpeg,png,bmp,webp,svg默认值: gif,jpg,jpeg,png,bmp,webp,svg
说明: 用于 uploadFile?type=image 接口,只允许图片格式上传。
; .env
[FILE]
FILE_EXT = gif,jpg,jpeg,png,bmp,webp,svg,doc,docx,xls,xlsx,ppt,pptx,pdf,zip,rar,txt,csv,mp3,mp4,sql,js,css默认值: 包含图片、文档、压缩包、音视频等常见格式。
说明: 用于 uploadFile 接口,允许所有合法文件格式。
[FILE]
UPLOAD_DIR = D:/uploads/rxthinkcmf
DOMAIN_URL =
MAX_SIZE = 10[FILE]
UPLOAD_DIR = /home/www/uploads/rxthinkcmf
DOMAIN_URL = https://test-cdn.example.com
MAX_SIZE = 10[FILE]
UPLOAD_DIR = /data/uploads/rxthinkcmf
DOMAIN_URL = https://cdn.example.com
MAX_SIZE = 10
IMAGE_EXT = jpg,jpeg,png,gif,bmp,webp
FILE_EXT = jpg,jpeg,png,gif,bmp,webp,doc,docx,xls,xlsx,pdf,zip,rar; 如果使用阿里云 OSS 等对象存储,domain_url 设为 OSS 域名
[FILE]
UPLOAD_DIR = /data/uploads/rxthinkcmf
DOMAIN_URL = https://your-bucket.oss-cn-hangzhou.aliyuncs.com
MAX_SIZE = 50{upload_dir}/ # upload_dir(上传根目录)
├── temp/ # 临时目录(temp_dir)
│ └── 20260920/ # 按日期分目录
│ ├── a1b2c3d4e5f6.jpg # 随机文件名(防止冲突)
│ └── f6e5d4c3b2a1.png
├── article/ # 正式目录(由 fileSaveDir 配置)
│ └── 20260920/
│ └── 143052_xK7pMn3q.jpg
├── example/
│ └── 20260920/
├── user/
│ └── avatar/
│ └── 20260920/
└── file_template/
└── 20260920/| 目录 | 说明 | 示例 |
|---|---|---|
temp/ | 临时文件目录 | 上传后暂存于此 |
{module}/ | 正式目录(按模块) | 由 Logic 的 fileSaveDir 配置 |
{date}/ | 日期子目录 | 20260920(自动创建) |
{random}.{ext} | 随机文件名 | a1b2c3d4e5f6.jpg(防止冲突) |
1. 前端上传 → upload_file()
保存到: {upload_dir}/temp/20260920/a1b2c3d4e5f6.jpg
返回: https://cdn.example.com/temp/20260920/a1b2c3d4e5f6.jpg
2. 前端提交表单 → 携带 fileUrl
POST /api/example/add { name: "测试", avatar: "https://..." }
3. BaseLogic::add() → save_file()
检测到 temp/ → 移动到正式目录
{upload_dir}/temp/20260920/a1b2c3d4e5f6.jpg
→ {upload_dir}/example/20260920/a1b2c3d4e5f6.jpg
返回相对路径入库: /uploads/example/20260920/a1b2c3d4e5f6.jpg
4. BaseLogic::detail() → get_file_url()
相对路径 → 拼接域名
/uploads/example/20260920/a1b2c3d4e5f6.jpg
→ https://cdn.example.com/uploads/example/20260920/a1b2c3d4e5f6.jpgclass ArticleLogic extends BaseTenantLogic
{
/**
* 需要自动处理的文件上传字段
*
* @var array
*/
protected array $fileFields = ['cover'];
/**
* 文件保存的子目录
*
* @var string
*/
protected string $fileSaveDir = 'article';
}实际路径映射:
配置:
upload_dir = /data/uploads/rxthinkcmf
fileSaveDir = article
结果:
临时文件: /data/uploads/rxthinkcmf/temp/20260920/abc.jpg
正式文件: /data/uploads/rxthinkcmf/article/20260920/abc.jpg
数据库存: /uploads/article/20260920/abc.jpg
前端显示: https://cdn.example.com/uploads/article/20260920/abc.jpg# 配置 Nginx 直接处理文件请求,不经过 PHP
location /uploads/ {
alias /data/uploads/rxthinkcmf/;
expires 30d;
add_header Cache-Control "public, immutable";
}# 安全:禁止上传目录执行 PHP 文件
location ~* /uploads/.*\.php$ {
deny all;
}location ~ /\. {
deny all;
}原因: upload_dir 目录没有写入权限。
解决:
# Linux
chmod -R 755 /data/uploads/rxthinkcmf
chown -R www:www /data/uploads/rxthinkcmf原因: domain_url 配置错误或 Nginx 未配置静态文件处理。
解决:
.env 中 DOMAIN_URL 是否正确/uploads/ 的 alias原因: PHP 配置限制了上传大小。
解决:
; php.ini
upload_max_filesize = 20M
post_max_size = 25M
max_execution_time = 300原因: temp/ 目录中的文件在表单提交后未被 save_file() 迁移。
解决: 定期清理 temp/ 目录中超过 1 天的文件:
# 定时任务:每天凌晨清理 1 天前的临时文件
find /data/uploads/rxthinkcmf/temp/ -type f -mtime +1 -delete| 建议 | 说明 |
|---|---|
| 上传目录放在项目外 | 防止被 Web 直接访问源码 |
| Nginx 禁止执行 PHP | 防止上传恶意 PHP 文件并执行 |
| 扩展名白名单 | 只允许已知安全的文件类型 |
| MIME 类型检查 | finfo 检测真实 MIME,防止伪造扩展名 |
| 随机文件名 | 防止路径遍历和文件名注入 |
| 文件大小限制 | 防止大文件 DoS 攻击 |
| 定期清理临时文件 | 避免磁盘空间被占满 |