PHP使用CURL上傳文件只需發送一個POST請求就能夠了,在請求中設置某個字段爲須要上傳的文件全路徑,而且以「@」開頭,而後使用CURL把該變量以POST方式發送到服務器,在服務端便可以從超級全局變量$_FILES中取到相應的上傳文件信息。php
下面咱們以一個例子來展現這個過程。python
假設本地有一個文本文件log.txt,其路徑爲「/www/test/log.txt」,內容以下:數組
this is a file for test
hello PythonTab!
爲了把這個文件上傳給服務端的腳本http://bbs.pythontab.com/upload.php,咱們在本地寫了一個名爲curl_file.php的腳本,內容以下:服務器
1 <?php 2 $url = "http://bbs.pythontab.com/upload.php"; 3 $post_data = array( 4 "foo" => "bar", 5 //要上傳的本地文件地址 6 "upload" = > "@/www/test/log.txt" 7 ); 8 $ch = curl_init(); 9 curl_setopt($ch , CURLOPT_URL , $url); 10 curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); 11 curl_setopt($ch , CURLOPT_POST, 1); 12 curl_setopt($ch , CURLOPT_POSTFIELDS, $post_data); 13 $output = curl_exec($ch); 14 curl_close($ch); 15 echo $output; 16 ?>
curl_file.php的邏輯很簡單,設置POST變量$post_data,其中upload指向須要發送的文件。這裏要注意,咱們以前使用POST都是發送一個字符串,而後在服務器端使用file_get_contents(「php//input」)來獲取該字符串,和這裏的用法不同,其實POST也能夠像GET同樣,發送鍵值對。在服務端有一個超級全局變量$_POST能夠像$_GET同樣,獲取相應的POST數據的值。須要注意的是,上傳文件的變量不是存在着$_POST中,而是在$_FILES中。app
爲了展現服務端收到上述代碼的文件上傳請求的邏輯,咱們在upload.php中寫了如下代碼:curl
1 <?php 2 echo var_export($_FILES,true); 3 echo file_get_contents($_FILES['upload']['tmp_name']); 4 copy($_FILES['upload']['tmp_name'], "./log_copy.txt"); 5 ?>
upload.php首先使用var_export將$_FILES變量輸出到標準輸出,而後使用file_get_contents讀取$_FILES[‘upload’][‘tmp_name’]所指文件的內容,並輸出到標準輸出,而後把$_FILES[‘upload’][‘tmp_name’]所指文件自制到當前目錄的log_copy.txt文件中。該腳本的標準輸出以下:post
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腳本的最後一行就是把臨時文件複製到咱們的目標文件中。this