分析(直接实践是最好的。。。。。):
一、Ningx 上传(
1.安装Nginx 的模块文件(upload):https://www.nginx.com/resources/wiki/modules/upload/,默认Nginx 肯定是没安装这个扩展模块的,你可以准备删除Nginx重新去官网下载一个最新稳定版本,并且进行编译吧。。。。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # Upload form should be submitted to this location location /upload { # Pass altered request body to this location upload_pass /upload .php; # Store files to this directory # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist<br><br>这里是扔到10个文件夹里去 upload_store /usr/share/nginx/html/file 1; # Allow uploaded files to be read only by user upload_store_access user:r; 就是在这里,他会自动给你命名。 # Set specified fields in request body upload_set_form_field "${upload_field_name}_name" $upload_file_name; upload_set_form_field "${upload_field_name}_content_type" $upload_content_type; upload_set_form_field "${upload_field_name}_path" $upload_tmp_path; # Inform backend about hash and size of a file upload_aggregate_form_field "${upload_field_name}_md5" $upload_file_md5; upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size; upload_pass_form_field "^submit$|^description$" ; } <br>这里是个大坑,因为如果默认就是当前的服务器的80端口,配置这个是会出错的,我就直接没用代理,直接 |
1 | upload_pass /upload .php; |
1 | #如果是当前端口,设置proxy_pass会出现错误 <br># Pass altered request body to a backend <br>#location @test {<br># proxy_pass htpp://127.0.0.1; <br>#} |
2.Nginx的某个路由(看我下面的配置文件)检测到上传请求后,会分别将各个你定义的form file name,上传到不同的文件夹,一共是10个(创建10个文件夹,命名0 1 2 3 ...),文件位置自定义(但一定要包含那10个文件夹,这个切记),一定要检测你创建的文件夹Nginx是否具有写入权限,这个可以自己看log(这个相当重要),如果你配置完成后想玩点新花样,可以自己玩玩,还可以限制上传速度之类的,而且可以做转发,如果你配置的代理服务器本身就做了URL反向代理,那肯定可以转发上传文件到多个Nginx服务器(上传文件提交信息,比如文件位置在哪儿之类的。)去滴。。。
二、直接PHP上传
PHP上传文件,本身就要配置Nginx 模块,所以很多人会搞混,其实两者是有差异的,
正常的上传流程:html 提交上传文件,nginx 收到后 扔到tmp目录,PHP收到后,把TMP的上传文件扔到自己想放的文件夹。
-------------------------------------------------------------------
两者都需要编写HTML,直接提交给Nginx ,在Upload Modules 配置好了,是可以直接接受多个文件上传的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!-- 这是提交给nginx --> <html lang= "CN" > < head > <meta charset= "UTF-8" > <title>Test upload< /title > < /head > <body> <h2>Select files to upload< /h2 > <form enctype= "multipart/form-data" action= "/upload" method= "post" > <input type = "file" name= "file" ><br><br> <input type = "file" name= "file1" ><br><br> <input type = "file" name= "file2" ><br> <input type = "submit" name= "submit" value= "Upload" > <input type = "hidden" name= "test" value= "value" > < /form > < /body > < /html > <!-- 这是直接提交给php --> <html lang= "CN" > < head > <meta charset= "UTF-8" > <title>Test upload< /title > < /head > <body> <h2>Select files to upload< /h2 > <form enctype= "multipart/form-data" action= "/upload.php" method= "post" > <input type = "file" name= "file" ><br> <input type = "submit" name= "submit" value= "Upload" > <input type = "hidden" name= "test" value= "value" > < /form > < /body > < /html > |
1:通过配置Ningx 安装 Upload Modules 进行 文件上传 再从PHP 接受 Ningx POST过来的参数。
2.直接通过编写PHP,从HTML 负责文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | server { listen 80; server_name localhost; charset utf-8; access_log /usr/local/nginx/logs/access .log main; client_max_body_size 100m; # Upload form should be submitted to this location location /upload { # Pass altered request body to this location upload_pass /upload .php; # Store files to this directory # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist upload_store /usr/share/nginx/html/file 1; # Allow uploaded files to be read only by user upload_store_access user:r; # Set specified fields in request body upload_set_form_field "${upload_field_name}_name" $upload_file_name; upload_set_form_field "${upload_field_name}_content_type" $upload_content_type; upload_set_form_field "${upload_field_name}_path" $upload_tmp_path; # Inform backend about hash and size of a file upload_aggregate_form_field "${upload_field_name}_md5" $upload_file_md5; upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size; upload_pass_form_field "^submit$|^description$" ; } #如果是当前端口,设置proxy_pass会出现错误 # Pass altered request body to a backend #location @test { # proxy_pass htpp://127.0.0.1; #} location / { root /usr/share/nginx/html/work/public ; index index.html index.htm index.php; } error_page 404 /404 .html; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x .html; location = /50x .html { root /usr/share/nginx/html ; } location ~ \.php$ { root /usr/share/nginx/html/work/public ; fastcgi_pass unix: /opt/remi/php70/root/run/lock/php-fcgi .sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 15d; } location ~ .*\.(js|css)?$ { expires 1d; } } |
自己感受~~~~~
然后贴上Demo PHP 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <?php header( 'Content-Type: text/html;charset=UTF-8' ); // 文件后缀=>文件类型 $ type = [ '.pdf' => 'application/pdf' ]; const FILE_DIR = '/usr/share/nginx/html/work/' ; // 如果非nginx upload module 上传文件 if (count(($ file = $_FILES[ 'file' ])) > 0) { if ($ file [ 'error' ] == 0) { // 判断文件类型是否存在,文件后缀是我们自己的key去定义 if ($fileType = array_search($ file [ 'type' ], $ type )) { // 以当前的时间命名目录 $date_dir = date ( 'Y-m-d' , time ()); // 如果目录没创建,我们就自己创建一个 if (!is_dir(FILE_DIR . $date_dir)) { if (! mkdir (FILE_DIR . $date_dir)) { return header( 'location:503.html' ); } } // 文件的MD5+当前unix时间戳+一个5位随机数,如果此处需求频繁也可以用微秒时间戳 $filename = FILE_DIR . $date_dir . '/' . (md5_file($ file [ 'tmp_name' ]) . time () . rand(9999, 99999)) . $fileType; // 生成新的文件 if (rename($ file [ 'tmp_name' ], $filename)) { return header( 'Location: success.html' ); } } } switch ($ file [ 'error' ]) { case 1: http_response_code(400); exit ( '文件大小超出了服务器的空间大小' ); case 2: http_response_code(400); exit ( '要上传的文件大小超出浏览器限制' ); case 3: http_response_code(400); exit ( '文件仅部分被上传' ); case 4: http_response_code(404); exit ( '没有找到要上传的文件' ); case 5: http_response_code(503); exit ( '服务器临时文件夹丢失' ); case 6: http_response_code(503); exit ( '文件写入到临时文件夹出错' ); } } // 如果是nginx upload module if (count(($ file = $_POST)) > 0) { // 判断文件类型是否存在,文件后缀是我们自己的key去定义 if ($fileType = array_search($ file [ 'file_content_type' ], $ type )) { // 以当前的时间命名目录 $date_dir = date ( 'Y-m-d' , time ()); // 如果目录没创建,我们就自己创建一个 if (!is_dir(FILE_DIR . $date_dir)) { if (! mkdir (FILE_DIR . $date_dir)) { return header( 'location:503.html' ); } } // 文件的MD5+当前unix时间戳+一个5位随机数,如果此处需求频繁也可以用微秒时间戳 $filename = FILE_DIR . $date_dir . '/' . (md5_file($ file [ 'file_path' ]) . time () . rand(9999, 99999)) . $fileType; // 生成新的文件 if (rename($ file [ 'file_path' ], $filename)) { return header( 'Location: success.html' ); } } } http_response_code(400); exit ( '错误操作方式!' ); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)