2011年9月18日 星期日

PHP上傳~解決中文檔名問題

近寫php上傳檔案的時候遇到了一些問題。

在這記錄下來,看能不能幫到跟我有一樣問題的人。


事實上,php的上傳檔案是非常基本的語法。

大概跟html的form表單是同等級的東西,其語法並不難,相當的好上手。

只不過在寫的時候,必須注意一些地方。

首先這是html的表單
<form action="./upload.php" enctype="multipart/form-data" method="POST">
Choose a file to upload: <input name="file" type="file" />
<input type="submit" value="Upload File" />
</form>


必須要加上enctype="multipart/form-data"把上傳的檔案編成表單的資料。

然後php接收由html傳來的資料。
$target_path = "uploadfiles/";   //上傳至uploadfiles這個資料夾
$target_path .= $_FILES['file']['name'];  //上傳之後命名的檔名

if(move_uploaded_file($_FILES['file']['tmp_name'], 
   iconv("UTF-8", "big5//TRANSLIT//IGNORE", $target_path ))) {
    echo "The file ". $_FILES['file']['name'] . " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
}




解說一下變數
$taget_path:上傳後檔案的存放位置,同時會命名。
$_FILES:這是一系列的變數陣列,上傳後的檔案資訊將會存放在這裡。
         利用print_r把它印出來的話可以看到有下列索引
  • $_FILES["file"]["name"]:上傳檔案的原始檔名。
  • $_FILES["file"]["type"]:上傳的檔案類型。
  • $_FILES["file"]["size"]:上傳的檔案原始大小,單位是bytes。
  • $_FILES["file"]["tmp_name"]:上傳檔案後的暫存資料夾位置。
  • $_FILES["file"]["error"]:如果檔案上傳有錯誤,可以顯示錯誤代碼。

錯誤代碼:
0:正常運行,傳回0。
1:超過php.ini中設定的upload_max_filesize大小。
2:上傳的檔案超過html form中的最大尺寸。
3:只有部份上傳成功。
4:沒有指定上傳檔案。
6:找不到暫存資料夾。
7:上傳寫入失敗。
8:有其它php程式阻止了檔案上傳。

官方說明:
http://php.net/manual/en/features.file-upload.errors.php



接下來就是中文檔名上傳的問題。

move_uploaded_file()會有沒辦法解析中文檔名的問題。

這個問題我們必須要用iconv來轉換編碼。

範例:
iconv("UTF-8", "big5//TRANSLIT//IGNORE", $target_path )

utf-8、big5都是編碼的一種,視個人情況可以改成其它編碼。
後面的//TRANSLIT//IGNORE,則是表示如果找不到對應的編碼,可以替換成相似的編碼或略過。

到這邊,大部份的問題都可以解決了。
接下來看個人要加什麼判斷就都隨意了。

這是我最後寫的程式碼:

if($_FILES["uploadedfile"]["error"] == 0 && is_uploaded_file($_FILES['uploadedfile']['tmp_name'])){
     if($_FILES['uploadedfile']['type'] == 'image/jpeg'){
          if(file_exists($target_path)){
               echo '<script>alert("檔案已存在,請勿重覆上傳。");</script>';
          }else{
               if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'],  iconv("UTF-8", "big5//TRANSLIT//IGNORE", $target_path))) {
                    echo "<script>alert('The file ".  basename( $_FILES['uploadedfile']['name']). " has been uploaded');</script>";
               } else{
                    echo "<script>alert('There was an error uploading the file, please try again!');</script>";
               }
          }
     }else{
     echo '<script>alert("請上傳.jpg檔");</script>';
     }
}



由於我是寫圖片的上傳,所以我限制只能上傳jpg的檔案。
利用$_FILES['uploadedfile']['type']判斷可以作到這一點。
 
然後也用is_uploaded_file檢查了是不是上傳的檔案,如果是的話才從暫存移到伺服器中,再判斷檔案有沒有重覆。

這樣的寫法,個人覺得相當的不優雅,用了一堆if判斷。
不過目前,我程度大概就到這邊而已了。

如果有更好的寫法,也歡迎你提出來討論,順便教教不成材的我。

Hpoe you like it!

後記
開學了,講這種話感覺自己似乎像個小學生一般,其實已經是老鳥一隻了。

聽到同學說開學沒有開學的感覺。

不過我們放假也沒放假的感覺啊,真是奇妙。

總之,還是要加油啦!



0 comments:

張貼留言