签入版本
This commit is contained in:
@@ -0,0 +1,335 @@
|
||||
# 7.2 上传配置详解
|
||||
|
||||
:::tip 概述
|
||||
文件上传配置定义在 `config/file.php` 和 `.env` 中,控制上传目录、域名、大小限制、允许的文件类型等。所有值通过 `env()` 函数从 `.env` 文件读取,支持多环境切换。
|
||||
:::
|
||||
|
||||
## 配置文件
|
||||
|
||||
```php
|
||||
// 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) |
|
||||
|
||||
### upload_dir — 上传根目录
|
||||
|
||||
```ini
|
||||
; .env
|
||||
[FILE]
|
||||
UPLOAD_DIR = D:/uploads/rxthinkcmf
|
||||
```
|
||||
|
||||
**要求:**
|
||||
- 必须是绝对路径
|
||||
- 目录必须存在且有写入权限
|
||||
- 生产环境建议放在项目目录外(防止被 Web 直接访问)
|
||||
|
||||
**各环境示例:**
|
||||
|
||||
| 环境 | 路径示例 |
|
||||
|------|---------|
|
||||
| Windows 开发 | `D:/uploads/rxthinkcmf` |
|
||||
| Linux 开发 | `/home/www/uploads/rxthinkcmf` |
|
||||
| Linux 生产 | `/data/uploads/rxthinkcmf` |
|
||||
| Docker | `/uploads/rxthinkcmf`(挂载卷) |
|
||||
|
||||
### domain_url — 文件访问域名
|
||||
|
||||
```ini
|
||||
; .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` |
|
||||
|
||||
### max_size — 文件大小限制
|
||||
|
||||
```ini
|
||||
; .env
|
||||
[FILE]
|
||||
MAX_SIZE = 10
|
||||
```
|
||||
|
||||
**单位:** MB(配置文件中会自动转换为字节:`10 * 1024 * 1024`)
|
||||
|
||||
**建议值:**
|
||||
|
||||
| 场景 | 建议值 | 说明 |
|
||||
|------|--------|------|
|
||||
| 头像上传 | 2 MB | 图片通常不会太大 |
|
||||
| 文章封面 | 5 MB | 压缩后的图片 |
|
||||
| 通用文件上传 | 10 MB | 默认值 |
|
||||
| 文档上传 | 20 MB | PDF/Word 等 |
|
||||
| 视频上传 | 100 MB | 需配合分片上传 |
|
||||
|
||||
### image_ext — 图片允许后缀
|
||||
|
||||
```ini
|
||||
; .env
|
||||
[FILE]
|
||||
IMAGE_EXT = gif,jpg,jpeg,png,bmp,webp,svg
|
||||
```
|
||||
|
||||
**默认值:** `gif,jpg,jpeg,png,bmp,webp,svg`
|
||||
|
||||
**说明:** 用于 `uploadFile?type=image` 接口,只允许图片格式上传。
|
||||
|
||||
### file_ext — 文件允许后缀
|
||||
|
||||
```ini
|
||||
; .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` 接口,允许所有合法文件格式。
|
||||
|
||||
## .env 配置示例
|
||||
|
||||
### 开发环境
|
||||
|
||||
```ini
|
||||
[FILE]
|
||||
UPLOAD_DIR = D:/uploads/rxthinkcmf
|
||||
DOMAIN_URL =
|
||||
MAX_SIZE = 10
|
||||
```
|
||||
|
||||
### 测试环境
|
||||
|
||||
```ini
|
||||
[FILE]
|
||||
UPLOAD_DIR = /home/www/uploads/rxthinkcmf
|
||||
DOMAIN_URL = https://test-cdn.example.com
|
||||
MAX_SIZE = 10
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
|
||||
```ini
|
||||
[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)
|
||||
|
||||
```ini
|
||||
; 如果使用阿里云 OSS 等对象存储,domain_url 设为 OSS 域名
|
||||
[FILE]
|
||||
UPLOAD_DIR = /data/uploads/rxthinkcmf
|
||||
DOMAIN_URL = https://your-bucket.oss-cn-hangzhou.aliyuncs.com
|
||||
MAX_SIZE = 50
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```text
|
||||
{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`(防止冲突) |
|
||||
|
||||
## 文件生命周期
|
||||
|
||||
```text
|
||||
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.jpg
|
||||
```
|
||||
|
||||
## 与 Logic 层的配合
|
||||
|
||||
```php
|
||||
class ArticleLogic extends BaseTenantLogic
|
||||
{
|
||||
/**
|
||||
* 需要自动处理的文件上传字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $fileFields = ['cover'];
|
||||
|
||||
/**
|
||||
* 文件保存的子目录
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $fileSaveDir = 'article';
|
||||
}
|
||||
```
|
||||
|
||||
**实际路径映射:**
|
||||
|
||||
```text
|
||||
配置:
|
||||
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 配置
|
||||
|
||||
### 静态文件直接由 Nginx 返回
|
||||
|
||||
```nginx
|
||||
# 配置 Nginx 直接处理文件请求,不经过 PHP
|
||||
location /uploads/ {
|
||||
alias /data/uploads/rxthinkcmf/;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
```
|
||||
|
||||
### 禁止上传目录执行 PHP
|
||||
|
||||
```nginx
|
||||
# 安全:禁止上传目录执行 PHP 文件
|
||||
location ~* /uploads/.*\.php$ {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
### 禁止访问隐藏文件
|
||||
|
||||
```nginx
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 问题 1:上传提示"目录不可写"
|
||||
|
||||
**原因:** `upload_dir` 目录没有写入权限。
|
||||
|
||||
**解决:**
|
||||
|
||||
```bash
|
||||
# Linux
|
||||
chmod -R 755 /data/uploads/rxthinkcmf
|
||||
chown -R www:www /data/uploads/rxthinkcmf
|
||||
```
|
||||
|
||||
### 问题 2:上传后图片不显示
|
||||
|
||||
**原因:** `domain_url` 配置错误或 Nginx 未配置静态文件处理。
|
||||
|
||||
**解决:**
|
||||
1. 检查 `.env` 中 `DOMAIN_URL` 是否正确
|
||||
2. 检查 Nginx 是否配置了 `/uploads/` 的 alias
|
||||
3. 浏览器打开图片 URL 看是否能直接访问
|
||||
|
||||
### 问题 3:文件大小限制不生效
|
||||
|
||||
**原因:** PHP 配置限制了上传大小。
|
||||
|
||||
**解决:**
|
||||
|
||||
```ini
|
||||
; php.ini
|
||||
upload_max_filesize = 20M
|
||||
post_max_size = 25M
|
||||
max_execution_time = 300
|
||||
```
|
||||
|
||||
### 问题 4:临时文件未清理
|
||||
|
||||
**原因:** `temp/` 目录中的文件在表单提交后未被 `save_file()` 迁移。
|
||||
|
||||
**解决:** 定期清理 `temp/` 目录中超过 1 天的文件:
|
||||
|
||||
```bash
|
||||
# 定时任务:每天凌晨清理 1 天前的临时文件
|
||||
find /data/uploads/rxthinkcmf/temp/ -type f -mtime +1 -delete
|
||||
```
|
||||
|
||||
## 安全建议
|
||||
|
||||
| 建议 | 说明 |
|
||||
|------|------|
|
||||
| 上传目录放在项目外 | 防止被 Web 直接访问源码 |
|
||||
| Nginx 禁止执行 PHP | 防止上传恶意 PHP 文件并执行 |
|
||||
| 扩展名白名单 | 只允许已知安全的文件类型 |
|
||||
| MIME 类型检查 | `finfo` 检测真实 MIME,防止伪造扩展名 |
|
||||
| 随机文件名 | 防止路径遍历和文件名注入 |
|
||||
| 文件大小限制 | 防止大文件 DoS 攻击 |
|
||||
| 定期清理临时文件 | 避免磁盘空间被占满 |
|
||||
Reference in New Issue
Block a user