php 文件上传
环境
- ubuntu 22.04
- thinkphp 6.1.0
- php-fpm8.1
- nginx 1.18.0
实现文件上传
本质上就是 html 页面这边提交一个表单, 请求上传文件
<form action="http://192.168.1.13:8888/view/upload" method="post" name="file_upload" target="_blank" enctype="multipart/form-data">
<table>
<tr>
<td>file name: </td>
<td><input name="upload_file", type="file"></td>
</tr>
<tr>
<td><input name="submit_button", type="submit", value="submit"></td>
</tr>
</table>
</form>
然后php 这边获取相关变量, 并且保存相关文件.
// 尝试存储文件
if ($_FILES['upload_file']['error'] == 0) { // 文件上传成功
// 存储文件
// 不会自动创建文件夹; 需要有 www-data 的写入权限
// 文件大小限制在php 中配置, 我这里使用的是php-fpm来解释php文件, 所以在 /etc/php/8.1/fpm/php.ini 中配置.
// (File Uploads)
// 临时文件会被 php-fpm 自动删除
$file_path = '/var/www/html/test/learning-php/upload/';
move_uploaded_file($_FILES['upload_file']['tmp_name'], $file_path . $_FILES['upload_file']['name']);
}
一些需要注意的点
- 上传文件, 首先会生成一个临时文件, 默认在
/tmp/
目录下, 可以在php.ini
配置文件中修改位置. - 跟上传文件相关的变量在
php
中存储在变量$_FILES
中, 在thinkphp中可以通过dump()
方法打印输出.
dump($_FILES)
输出如下图片:
- 使用
move_uploaded_file()
方法将文件保存起来, 即将临时文件保存到真正需要保存的位置. - 没有文件也会上传成功的, 需要服务器自己判断.
- 上传文件相关限制, 比如文件大小限制等, 在
php.ini
中配置, 可以搜索关键字file upload
快速定位. - 默认
php-fpm
的执行用户是www-data
, 所以需要保证目标文件夹有www-data
用户的写入权限. - 默认不会创建目的地文件夹, 上传前需要自己先创建好.
- 如何有组织, 有结构的上传整个文件夹? 好像不行, 因为上传不会创建相关的文件夹, 比如文件名为
sub/test.text
,php
拿到的只是test.text
.
扩展
其实nginx
本身可以通过配置直接实现一个文件上传服务器, 手册上能找到这句话
A file uploaded with the PUT method is first written to a temporary file, and then the file is renamed.
我需要做的就是通过配置控制这个文件临时文件写在哪里, 然后指定真正的位置, 再加上一些限制, 比如限制文件大小等. 我的配置如下
访问方式如下:
curl -T /path/to/filename http://host:port/upload/custum-filename
.
本地简单的测试是没有问题的.
也有一些担忧, 没有看到实际相关的例子, 也没有经过专业的检测, 不知道一个正常的上传服务器是否可以这么做.