Upload
<br/>
>i 本文档的最新修订日期是:
> **2024-03-09**
# Upload ::
通过更便安全、捷的方式管理文件上传。
通常上传文件时,会将文件的完整路径存储于数据表中。这样做的弊端有很多:
* 文件路径写死在数据表中,不易修改;
* 传输路径及文件名可能带来额外的安全风险;
* 重复的文件路径占用数据库空间;
* 文件盗链风险。
因此将上传规则单独建表,并将上传的文件路径与随机生成的token建立映射,通过框架的Data模块使用文件或Redis缓存的方式缓存映射关系。上传文件时上传者将获得文件token,上传者提交数据时校验token是否有效(文件是否被上传),校验通过则将token存储于数据表内而不是存储完整的文件路径。
获取文件有两种方式:
* 【推荐】在代码中预先将token替换为实际存储路径,再传递给客户端;
* 建立一个中转页,根据客户端传递的token,作302跳转到真实文件地址。
本模块中没有实现对上传规则表的写操作,请自行根据数据表中的字段注释新建上传规则。
可根据上传记录表中的reference字段来清理未被引用的文件(上传了图片但没提交)。
可根据上传记录表中的status字段来进一步拓展文件上传流程(如图片压缩)。
可不定期修改上传规则表中的路径和实际文件的存储路径,实现物理防盗链(狗头)。
# 依赖
本模块依赖于框架模块 <font color="#c7254e">`Db`</font> 、 <font color="#c7254e">`Data`</font> 以及 <font color="#c7254e">`Load`</font> 。
本模块依赖于数据库使用。样例数据表位于 <font color="#c7254e">`/lib/sql/upload.sql`</font> 。
# 模块配置
配置文件位于 <font color="#c7254e">`/config/core/Upload.php`</font> 。
* **<font color="#ff6600">`rule_table`</font>** <font color="#0099ff">`(String)`</font> <font color="#bbbbbb">`'upload_rule'`</font> :
指定存储上传规则的数据表名。
* **<font color="#ff6600">`file_table`</font>** <font color="#0099ff">`(String)`</font> <font color="#bbbbbb">`'upload_file'`</font> :
指定存储上传记录的数据表名。
* **<font color="#ff6600">`rule_prefix`</font>** <font color="#0099ff">`(String)`</font> <font color="#bbbbbb">`'upload_rule'`</font> :
指定上传规则的缓存前缀。
* **<font color="#ff6600">`rule_prefix`</font>** <font color="#0099ff">`(String)`</font> <font color="#bbbbbb">`'upload_file'`</font> :
指定上传记录的缓存前缀。
* **<font color="#ff6600">`accept`</font>** <font color="#0099ff">`(Array)`</font> <font color="#bbbbbb">`(省略)`</font> :
此配置项为一个一维数组(Array),用以指定允许上传的文件后缀以及对应的MIME类型。<font color="#c7254e">`键`</font> 为文件后缀(不含 <font color="#c7254e">`.`</font> ), <font color="#c7254e">`值`</font> 为对应的MIME类型。
# 公共参数
* **<font color="#ff6600">`rule(规则)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`默认值见方法参数`</font>:
用以指定文件上传规则的代码。
* **<font color="#ff6600">`refresh(刷新)`</font>** <font color="#0099ff">`(Bool)`</font> <font color="#BBBBBB">`默认值见方法参数`</font>:
用以指定是否忽略缓存,直接从数据库中获取最新的上传记录或上传规则。
# getRule()
## 说明
**<font color="#0099ff"><font color="#ff6600">Upload</font> :: <font color="#ff6600">getRule</font> ( <kbd>传参数组</kbd> ) </font>**
获取指定的上传规则。
此方法 <font color="#c7254e">`支持`</font> 中文参数名。
## 参数
* **<font color="#ff6600">`rule(规则)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`<必须>`</font>:
详见本模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
* **<font color="#ff6600">`refresh(刷新)`</font>** <font color="#0099ff">`(Bool)`</font> <font color="#BBBBBB">`false`</font>:
详见本模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
## 返回
<font color="#0099ff">`(Array|Bool)`</font> 类型。
返回值与使用Db::select()方法进行查询后所获取的结果一致,但本方法会优先获取缓存数据。
如果返回值为 <font color="#c7254e">`false`</font> ,则代表规则不存在。
# getAccept()
## 说明
**<font color="#0099ff"><font color="#ff6600">Upload</font> :: <font color="#ff6600">getAccept</font> ( <kbd>传参数组</kbd> ) </font>**
获取允许上传的文件类型。
此方法 <font color="#c7254e">`支持`</font> 中文参数名。
## 参数
无。
## 返回
<font color="#0099ff">`(Array)`</font> 类型。
返回值与配置文件中 <font color="#c7254e">`accept`</font> 参数的值一致。
# load()
## 说明
**<font color="#0099ff"><font color="#ff6600">Upload</font> :: <font color="#ff6600">load</font> ( <kbd>传参数组</kbd> ) </font>**
上传一个文件。
此方法 <font color="#c7254e">`支持`</font> 中文参数名。
## 参数
* **<font color="#ff6600">`rule(规则)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`<必须>`</font>:
详见本模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
* **<font color="#ff6600">`name(名称)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`<必须>`</font>:
指定表单中的文件域字段(也就是HTML表单里文件域 <font color="#c7254e">`name`</font> 属性的值)。
此文件域仅支持单个文件上传。
* **<font color="#ff6600">`data(数据)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#BBBBBB">`[]`</font>:
详见 <font color="#c7254e">`Db`</font> 模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
此参数可以向上传记录表中自定义的字段(如有)添加数据。
## 返回
<font color="#0099ff">`(String)`</font> 类型。
返回值为一个32位随机字符串,此字符串作为查询文件的依据。
# query()
## 说明
**<font color="#0099ff"><font color="#ff6600">Upload</font> :: <font color="#ff6600">query</font> ( <kbd>传参数组</kbd> ) </font>**
根据指定的token和上传规则获取文件的实际存放路径。
此方法 <font color="#c7254e">`支持`</font> 中文参数名。
## 参数
* **<font color="#ff6600">`token(token)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`<必须>`</font>:
通过 <font color="#c7254e">`load()`</font> 方法获取到的文件token。
* **<font color="#ff6600">`rule(规则)`</font>** <font color="#0099ff">`(String)`</font> <font color="#BBBBBB">`<必须>`</font>:
详见本模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
* **<font color="#ff6600">`refresh(刷新)`</font>** <font color="#0099ff">`(Bool)`</font> <font color="#BBBBBB">`false`</font>:
详见本模块 <font color="#c7254e">`公共参数`</font> 部分的说明。
* **<font color="#ff6600">`field(字段)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#BBBBBB">`[]`</font>:
指定返回哪些上传记录表中自定义的字段(如有)。
数组 <font color="#c7254e">`键`</font> 无需定义, <font color="#c7254e">`值`</font> 为字段名。
* **<font color="#ff6600">`reference(引用)`</font>** <font color="#0099ff">`(Bool)`</font> <font color="#BBBBBB">`false`</font>:
如果值为 <font color="#c7254e">`true`</font> ,将修改上传记录表中 <font color="#c7254e">`reference`</font> 字段对应的值为 <font color="#c7254e">`1`</font> 。
可以通过上传记录表中 <font color="#c7254e">`reference`</font> 字段对应的值清理未引用(这里的未引用是指文件token从未被引用)的文件。
通常传入 <font color="#c7254e">`true`</font> 的时机是提交发布/修改内容时校验token是否存在时。不涉及内容改动的查询,例如展示图片时请传入 <font color="#c7254e">`false`</font> 。
## 返回
<font color="#0099ff">`(String)`</font> 类型。
返回值为一个32位随机字符串,此字符串作为查询文件的依据。