1.背景
根据项目需求,注册模块用户需上传头像,要用到文件上传的功能。由于服务端是用PHP来写的,所以本人去PHP官网上进行了学习,稍微总结过程并记录下来。
2.详情
打开了PHP文件上传的官方网页:https://www.php.net/manual/zh/features.file-upload.post-method.php。可以看到PHP 能够接受任何来自符合 RFC-1867 标准的浏览器上传的文件。于是乎本人又去大致了解了下RFC-1867标准。
一、HTTP文件上传
RFC1867是Form-based File Upload in HTML标准协议,此协议对HTML做出两项修改:
(1)为input元素的type属性增加了一个file选项。
(2)input标记可以具有accept属性,该属性能够指定可被上传的文件类型或文件格式列表。
另外,本标准还定义了一种新的MIME类型:multipart/form-data,并且含有<input type="file">的标记的表单时所应该采取的行为,用户可以自行更改标签,但这些元素必须包含在内。当HTML想让用户传输多个文件时候可以这样写:
<FORM ACTION="http://server.dom/cgi/handle" ENCTYPE="multipart/form-data" METHOD=POST> What is your name? <INPUT TYPE=TEXT NAME=submitter> What files are you sending? <INPUT TYPE=FILE NAME=pics> </FORM>
当用户将"Joe Blow"填入文本输入框, 将"file1.txt"文件填入文件输入框时,客户端将向服务端发送一下数据:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
二、PHP处理POST上传的文件
全局变量 $_FILES 包含有所有上传的文件信息。 数组的内容来自以下范例表单。我们假设文件上传字段的名称如下例所示,为 userfile。名称可随意命名。
$_FILES['userfile']['name']
客户端机器文件的原名称。
$_FILES['userfile']['type']
文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是“image/gif
”。不过此 MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。
$_FILES['userfile']['size']
已上传文件的大小,单位为字节。
$_FILES['userfile']['tmp_name']
文件被上传后在服务端储存的临时文件名。
$_FILES['userfile']['error']
该文件上传相关的错误代码。
三、PHP写文件系统
文件被上传后,默认地会被储存到服务端的默认临时目录中,除非 php.ini 中的 upload_tmp_dir 设置为其它的路径。服务端的默认临时目录可以通过更改 PHP 运行环境的环境变量 TMPDIR 来重新设置,但是在 PHP 脚本内部通过运行 putenv() 函数来设置是不起作用的。该环境变量也可以用来确认其它的操作也是在上传的文件上进行的。PHP用move_uploaded_file()方法将临时目录的文件移动到项目的指定位置。PHP实现文件上传的案例如下所示:
<html> <body> <form action="http://xxxx/upload_file.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file" id="file" /> <br /> <input type="submit" name="submit" value="Submit" /> </form> </body> </html>
<?php if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/jpg") || ($_FILES["file"]["type"] == "image/pjpeg") || ($_FILES["file"]["type"] == "image/x-png") || ($_FILES["file"]["type"] == "image/png")) ) //文件大小B && ($_FILES["file"]["size"] < 2000000) { if ($_FILES["file"]["error"] > 0) //出错 { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else //上传文件当临时系统 { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists("upload/" . $_FILES["file"]["name"])) //文件存在 { echo $_FILES["file"]["name"] . " already exists. "; } else //移动文件到指定位置 { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } } else { echo "Invalid file"; //文件类型错误 } ?>