這里來看看php中如何上傳圖片的
先看代碼check_image.php
<html> <head> <title></title> <style type="text/css"></style> </head> <body> <form action="check_image.php" method="post" enctype="multipart/form-data"> <table> <tr> <td>Your username</td> <td><input type="text" name="username" /></td> </tr> <tr> <td>Upload image*</td> <td><input type="file" name="uploadfile"/></td> </tr> <tr> <td colspan="2"> <small><em> * Acceptable image formats include: GIF, JPG/JPEG and PNG.</em></small> </td> </tr> <tr> <td>Image Caption</td> <td><input type="text" name="caption"/></td> </tr> <tr> <td colspan="2" style="text-align:center;"> <input type="submit" name="submit" value="Upload" /> </td> </tr> </table> </form> </body> </html>
這里沒什么可以說的,都是常見的html標簽。
下面看看上傳的代碼check_image.php,重要的地方都做了注釋,整個過程是先根據那個<input type="file" name="uploadfile"/>指定的圖片路徑來創建一個圖片文件,然后再通過指定的上傳路徑生成這個圖片。
<?php $db = mysql_connect('localhost','root','Ctrip07185419') or die('can not connect to database'); mysql_select_db('moviesite',$db) or die(mysql_error($db)); //上傳文件的路徑 $dir = 'D:\Serious\phpdev\test\images'; /* $_FILES:用在當需要上傳二進制文件的地方,獲得該文件的相關信息 $_FILES['userfile']['name'] 客戶端機器文件的原名稱。 $_FILES['userfile']['type'] 文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif” $_FILES['userfile']['size'] 已上傳文件的大小,單位為字節 $_FILES['userfile']['tmp_name'] 文件被上傳后在服務端儲存的臨時文件名,注意不要寫成了$_FILES['userfile']['temp_name']很容易寫錯的,雖然tmp就是代表臨時的意思,但是這里用的縮寫 $_FILES['userfile']['error'] 和該文件上傳相關的錯誤代碼。['error'] */ if($_FILES['uploadfile']['error'] != UPLOAD_ERR_OK) { switch($_FILES['uploadfile']['error']) { case UPLOAD_ERR_INI_SIZE: //其值為 1,上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值 die('The upload file exceeds the upload_max_filesize directive in php.ini'); break; case UPLOAD_ERR_FORM_SIZE: //其值為 2,上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值 die('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'); break; case UPLOAD_ERR_PARTIAL: //其值為 3,文件只有部分被上傳 die('The uploaded file was only partially uploaded.'); break; case UPLOAD_ERR_NO_FILE: //其值為 4,沒有文件被上傳 die('No file was uploaded.'); break; case UPLOAD_ERR_NO_TMP_DIR: //其值為 6,找不到臨時文件夾 die('The server is missing a temporary folder.'); break; case UPLOAD_ERR_CANT_WRITE: //其值為 7,文件寫入失敗 die('The server failed to write the uploaded file to disk.'); break; case UPLOAD_ERR_EXTENSION: //其他異常 die('File upload stopped by extension.'); break; } } $image_caption = $_POST['caption']; $image_username = $_POST['username']; $image_date = date('Y-m-D'); /*getimagesize方法返回一個數組, $width : 索引 0 包含圖像寬度的像素值, $height : 索引 1 包含圖像高度的像素值, $type : 索引 2 是圖像類型的標記: 1 = GIF,2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order),8 = TIFF(motorola byte order), 9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM, $attr : 索引 3 是文本字符串,內容為“height="yyy" width="xxx"”,可直接用於 IMG 標記 */ list($width,$height,$type,$attr) = getimagesize($_FILES['uploadfile']['tmp_name']); //imagecreatefromgXXX方法從一個url路徑中創建一個新的圖片 switch($type) { case IMAGETYPE_GIF: $image = imagecreatefromgif($_FILES['uploadfile']['tmp_name']) or die('The file you upload was not supported filetype'); $ext = '.gif'; break; case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($_FILES['uploadfile']['tmp_name']) or die('The file you upload was not supported filetype'); $ext = '.jpg'; break; case IMAGETYPE_PNG: $image = imagecreatefrompng($_FILES['uploadfile']['tmp_name']) or die('The file you upload was not supported filetype'); $ext = '.png'; break; default : die('The file you uploaded was not a supported filetype.'); } $query = 'insert into images(image_caption,image_username,image_date) values ("'.$image_caption.'","'.$image_username.'",now())'; mysql_query($query , $db) or die(mysql_error($db)); $last_id = mysql_insert_id(); //用寫入的id作為圖片的名字,避免同名的文件存放在同一目錄中 $imagename = $last_id.$ext; $query = 'update images set image_filename="'.$imagename.'" where image_id='.$last_id; mysql_query($query , $db) or die(mysql_error($db)); //有url指定的圖片創建圖片並保存到指定目錄 switch($type) { case IMAGETYPE_GIF: imagegif($image,$dir.'/'.$imagename); break; case IMAGETYPE_JPEG: imagejpeg($image,$dir.'/'.$imagename); break; case IMAGETYPE_PNG: imagepng($image,$dir.'/'.$imagename); break; } //銷毀由url生成的圖片 imagedestroy($image); ?> <html> <head> <title></title> </head> <body> <h1>So how does it feel to be famous</h1> <p>Here is the picture you just upload to servers</p> <img src="images/<?php echo $imagename;?>" alt="upload image" /> <table> <tr> <td>Image save as:</td><td><?php echo $imagename?></td> <td>Image type:</td><td><?php echo $ext?></td> <td>Height:</td><td><?php echo $height?></td> <td>Width:</td><td><?php echo $width?></td> <td>Upload date:</td><td><?php echo $image_date?></td> </tr> </table> </body> </html>
最后寫道數據庫中的信息如下:
在upload_image.php這個頁面中同圖片file控件使用戶可以通過瀏覽自己的本地文件選擇要上傳的文件,其次還要對form的enctype屬性進行設置,這里需要上傳文件所以在發送到服務器之前不對表單數據進行編碼,需要將值設置成mulitpart/form-data,還要注意這里method屬性應該設置成post,如果設置成get的話,不能正常地上傳文件。
在check_image.php這個頁面中則需要檢查文件類型,然后將文件信息寫入到數據庫中,最后在指定的路徑中寫入文件並輸出文件信息,如果不符合類型或者寫入的過程中有錯誤則會輸出錯誤並跳出程序,輸出錯誤信息。
php中使用$_FILES數組來存儲上傳的文件信息,這個數組是多維的,第一維的KEY是上傳控件的name屬性值,如果在一個頁面中有多個上傳控件的話可以使用不同的KEY值來區分它,第二維參數名字及含義如下:
name:在本地的文件名字
type:圖片文件的擴展名字
size:圖片文件的大小以byte來計算
tmp_name:在上傳到的新的目錄上的文件名字
error:上傳過程中出現的錯誤
在上傳到目錄之前文件以一種臨時文件的形式出現,上傳完之后一定要銷毀這個臨時文件。
type屬性是要上傳文件的擴展名字,例如:image/jpg,image/gif,記住這個名字是通過瀏覽器來獲得的,可能不正確,不懷好意的用戶可能會偽造這個文件擴展名。
size屬性表示要上傳文件的大小,它是以byte來計算,
error屬性來告訴客戶端上傳過程中的一些錯誤代碼,通過這些代碼將能編寫出更加健壯的程序,error的枚舉值如下:
UPLOAD_ERR_OK:文件上傳成功
UPLOAD_ERR_INI:上傳文件超過php.ini文件中規定最大上傳文件大小
UPLOAD_ERR_FORM_SIZE:上傳文件超過HTML文件中規定的文件上傳大小限制
UPLOAD_ERR_PARTIAL:上傳的文件不完整
UPLOAD_ERR_NO_FILE:在php.ini中沒有指定臨時文件夾
UPLOAD_ERR_CANT_WRITE:文件夾沒有寫入權限,php不能寫入
UPLOAD_ERR_EXTENSION:上傳文件被php中斷
很多地方可以對上傳文件進行限制,當上傳文件大小超過php.ini中文件大小的時候將返回UPLOAD_ERR_INI值,默認情況下這個值是2M,如下:
upload_max_filesize = 2M
如果要修改這個值,可能還需要同時修改 post_max_size這個,upload_max_filesize限制上傳文件的大小,post_max_size限制整個post數據大小,所以如果upload_max_filesize大於post_max_size,上傳也可能失敗,所以這兩個值的關系應該是post_max_size大於upload_max_filesize。
當文件大小大於html頁面中一個特定的隱藏域設置大小的時候將返回UPLOAD_ERR_FORM_SIZE,這個隱藏域的設置如下:
<input type=”hidden” name=”MAX_FILE_SIZE” value=”262144”/>
<input type=”file” name=”uploadfile”/>
要注意的是這個隱藏域的位置應該在上傳控件之上。這個值不一定有用,不懷好意的人可能在上傳過程中修改文件的大小信息進而蒙騙服務器。正常情況下這個值還是有用的,可以用它來顯示文件大小超過限制的信息。
當文件上載成功之后,getimagesize()方法可以返回一個5個元素的數組,用來獲取文件的信息,例如:
下標為0的元素:圖片的寬度
下標為1的元素:圖片的高度
下標為2的元素:一個枚舉,表示圖片的類型
下標為3的元素:一個字符串類似於height=“ yyy ” width=“ xxx ”
下標為4的元素:文件的擴展名稱,簡單說還是文件的類型
確定圖片類型之后,將文件讀入內存,imagecreatefrom*()方法打開文件並返回句柄,記住文件是首先放到一個臨時的文件夾中,然后再寫入到最終路徑中,最后銷毀,通常是使用 move_uploaded_file() 方法來實現的,第一個參數是要文件名字,第二個參數是文件上傳的路徑,如果文件類型是非法的話imagecreatefrom*()方法會返回錯誤。
同時根據文件類型制定文件擴展,如果上傳的文件不再指定的范圍內,將返回信息The file you uploaded was not a supported filetype。如果一切進行的順利的話,將文件信息寫入倒數據庫中。
最后imagegif() , imagejpeg() , imagepng() 這類方法將文件通過$image方法得到的結果寫入到指定的文件名中,imagejpeg()方法有第三個參數,這個參數將會影響圖片的質量,100表示最小的壓縮比例,質量也是最好的,同理0質量是最差的。
imagedestroy()方法將$image方法占用的內存資源釋放掉,php會自動釋放掉這些資源,但是如果手動釋放表示我們有一個好的習慣。最后將上傳的文件顯示在頁面中,表示已經上傳成功。