POST 方法上傳
此功能允許使用者上傳文字和二進位檔案。透過 PHP 的驗證和檔案處理函式,您可以完全控制允許誰上傳,以及上傳檔案後要執行的操作。
PHP 能夠接收來自任何符合 RFC-1867 標準瀏覽器的檔案上傳。
注意:相關組態注意事項
另請參閱 php.ini 中的 file_uploads、upload_max_filesize、upload_tmp_dir、post_max_size 和 max_input_time 指令。
PHP 也支援 Netscape Composer 和 W3C 的 Amaya 用戶端所使用的 PUT 方法檔案上傳。請參閱 PUT 方法支援 以取得更多詳細資訊。
範例 1:檔案上傳表單
檔案上傳畫面可以透過建立一個特殊的表單來建立,該表單看起來像這樣
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
<!-- MAX_FILE_SIZE must precede the file input field -->
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<!-- Name of input element determines name in $_FILES array -->
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
以上範例中的 __URL__
應被取代,並指向一個 PHP 檔案。
MAX_FILE_SIZE
隱藏欄位(以位元組為單位測量)必須位於檔案輸入欄位之前,其值是 PHP 接受的最大檔案大小。此表單元素應始終使用,因為它可以讓使用者省去等待傳輸大檔案的麻煩,結果發現檔案太大而傳輸失敗。請記住:在瀏覽器端欺騙此設定很容易,因此永遠不要依賴此功能來阻止較大檔案。這只是應用程式用戶端使用者的一項便利功能。但是,伺服器端 PHP 針對最大大小的設定無法被欺騙。
注意:
請確保您的檔案上傳表單具有屬性 enctype="multipart/form-data"
,否則檔案上傳將無法運作。
全域 $_FILES 將包含所有上傳的檔案資訊。其內容來自範例表單如下。請注意,這假設使用了檔案上傳名稱userfile,如上述範例腳本中所使用。這可以是任何名稱。
- $_FILES['userfile']['name']
-
用戶端機器上檔案的原始名稱。
- $_FILES['userfile']['type']
-
檔案的 MIME 類型,如果瀏覽器提供了此資訊。範例是 "image/gif"
。但是,此 MIME 類型未在 PHP 端檢查,因此不要理所當然地接受其值。
- $_FILES['userfile']['size']
-
上傳檔案的大小,以位元組為單位。
- $_FILES['userfile']['tmp_name']
-
上傳檔案儲存在伺服器上的臨時檔案名稱。
- $_FILES['userfile']['error']
-
與此檔案上傳相關聯的 錯誤代碼。
- $_FILES['userfile']['full_path']
-
瀏覽器提交的完整路徑。此值不一定包含真實的目錄結構,且不可信任。自 PHP 8.1.0 起可用。
除非在 php.ini 中使用 upload_tmp_dir 指令指定了其他位置,否則預設情況下檔案將儲存在伺服器的預設臨時目錄中。可以透過在 PHP 執行環境中設定環境變數 TMPDIR 來變更伺服器的預設目錄。從 PHP 腳本中使用 putenv() 設定它將不起作用。此環境變數也可以用來確保其他操作正在處理上傳的檔案。
範例 2:驗證檔案上傳
另請參閱 is_uploaded_file() 和 move_uploaded_file() 的函式條目,以取得更多資訊。以下範例將處理來自表單的檔案上傳。
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "檔案有效,且已成功上傳。\n";
} else {
echo "可能的檔案上傳攻擊!\n";
}
echo '以下是一些更多的除錯資訊:';
print_r($_FILES);
print "</pre>";
?>
接收上傳檔案的 PHP 腳本應實作任何必要的邏輯,以判斷應如何處理上傳的檔案。例如,您可以使用 $_FILES['userfile']['size'] 變數來捨棄任何太小或太大的檔案。您可以使用 $_FILES['userfile']['type'] 變數來捨棄任何不符合特定類型條件的檔案,但僅將其作為一系列檢查中的第一個,因為此值完全由用戶端控制,且未在 PHP 端檢查。此外,您可以使用 $_FILES['userfile']['error'] 並根據 錯誤代碼 規劃您的邏輯。無論邏輯如何,您都應該從臨時目錄中刪除檔案或將其移動到其他位置。
如果您的表單中未選擇要上傳的檔案,則 PHP 會將 $_FILES['userfile']['size'] 回傳為 0,將 $_FILES['userfile']['tmp_name'] 回傳為 none。
如果檔案未被移走或重新命名,則該檔案會在請求結束時從臨時目錄中刪除。
範例 3:上傳檔案陣列
<form action="" method="post" enctype="multipart/form-data">
<p>Pictures:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Send" />
</p>
</form>
<?php
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
// basename() 可能可以防止檔案系統遍歷攻擊;
// 進一步驗證/清理檔案名稱可能是適當的
$name = basename($_FILES["pictures"]["name"][$key]);
move_uploaded_file($tmp_name, "data/$name");
}
}
?>
可以使用 會期上傳進度 實作檔案上傳進度列。