PHP使用CURL上傳檔案只需傳送一個POST請求就可以了,在請求中設定某個欄位為需要上傳的檔案全路徑,並且以“@”開頭,然後使用CURL把該變數以POST方式傳送到伺服器,在服務端即可以從超級全域性變數$_FILES中取到相應的上傳檔案資訊。
下面我們以一個例子來展示這個過程。
假設本地有一個文字檔案log.txt,其路徑為“/www/test/log.txt”,內容如下:
this is a file for test hello PythonTab!
為了把這個檔案上傳給服務端的指令碼http://www.pythontab.com/upload.php,我們在本地寫了一個名為curl_file.php的指令碼,內容如下:
"bar", //要上傳的本地檔案地址 "upload" = > "@/www/test/log.txt" ); $ch = curl_init(); curl_setopt($ch , CURLOPT_URL , $url); curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch , CURLOPT_POST, 1); curl_setopt($ch , CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output; ?>
curl_file.php的邏輯很簡單,設定POST變數$post_data,其中upload指向需要傳送的檔案。這裡要注意,我們之前使用POST都是傳送一個字串,然後在伺服器端使用file_get_contents(“php//input”)來獲取該字串,和這裡的用法不一樣,其實POST也可以像GET一樣,傳送鍵值對。在服務端有一個超級全域性變數$_POST可以像$_GET一樣,獲取相應的POST資料的值。需要注意的是,上傳檔案的變數不是存在著$_POST中,而是在$_FILES中。
為了展示服務端收到上述程式碼的檔案上傳請求的邏輯,我們在upload.php中寫了以下程式碼:
upload.php首先使用var_export將$_FILES變數輸出到標準輸出,然後使用file_get_contents讀取$_FILES[‘upload’][‘tmp_name’]所指檔案的內容,並輸出到標準輸出,然後把$_FILES[‘upload’][‘tmp_name’]所指檔案自制到當前目錄的log_copy.txt檔案中。該指令碼的標準輸出如下:
array( 'upload' => array( 'name' => 'log.txt', 'type' => 'application/octet-stream', 'tmp_name' => '/tmp/phpLUB59F', 'error' => 0, 'size' => 36, ) ) this is a file for test hello PythonTab!
可以看到$_FILES變數中有一個upload陣列,對應到上傳檔案描述資訊,其中name和type分別表示名稱和型別。tmp_name比較關鍵,服務端在接收到上傳檔案之後,會把檔案寫在一個臨時檔案中,這個臨時檔案的名字就是tmp_name的值,這也是為什麼我們讀取該檔案可以獲取一log.txt的檔案內容。一般在服務端接收到上傳檔案後都需要立即讀取該檔案或者把檔案複製到別外一個檔案中,因為tmp_name所指的臨時檔案在服務端指令碼執行完畢後會被刪除掉,upload.php指令碼的最後一行就是把臨時檔案複製到我們的目標檔案中。