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"; //文件類型錯誤 } ?>