在胡說之前,首先聲明,本文是建立在掌握php單文件上傳的基礎上,所以這裡就不贅述文件上傳服務器配置,表單設置該注意的地方了。
話不多少,直入主題,在請求頁面方面有兩種寫法(只呈現表單部分,以上傳三個文件為例。)
<form action="doAction.php" method="post" enctype="multipart/form-data">
請選擇我的上傳文件
<input type="file" name="myfile[]"/>
<input type="file" name="myfile[]" />
<input type="file" name="myfile[]" />
<input type="submit" value="上傳" />
</form>
<form action="doAction.php" method="post" enctype="multipart/form-data">
請選擇我的上傳文件
<input type="file" name="myfil1"/>
<input type="file" name="myfil2"/>
<input type="file" name="myfil3"/>
<input type="submit" value="上傳" />
</form>
兩個對比,發現僅僅是name的不同,第一個將name設置成數組的形式,而第二個則是我們通常設置也很容易想到的一種方法。
雖然表面上顯示的僅僅有一點點不同,但真正提交到doAction.php頁面的$_FILES則有很大不同。
第一種的$_FILES是一個三維數組,而第二種是二維數組,如下:

function getFiles(){
foreach($_FILES as $file){
$fileNum=count($file['name']);
if ($fileNum==1) {
$files=$file;
}else{
for ($i=0; $i < $fileNum; $i++) {
$files[$i]['name']=$file['name'][$i];
$files[$i]['type']=$file['type'][$i];
$files[$i]['tmp_name']=$file['tmp_name'][$i];
$files[$i]['error']=$file['error'][$i];
$files[$i]['size']=$file['size'][$i];
}
}
}
return $files;
}
通過這個函數,將$_FILES轉化為下面格式:

此刻,兩種上傳方式已經處在同一起跑線了,下面的工作便是編寫uploadFile()函數對每個文件進行上傳,這也是本文的重點。
文件上傳函數:
function uploadFile($file,$path='./uploads',$max_size,$allowExt){
$filename=$file['name'];
$type=$file['type'];
$temp_name=$file['tmp_name'];
$error=$file['error'];
$size=$file['size'];
if ($error==UPLOAD_ERR_OK) {
if ($size>$max_size) {
$res['mes']=$filename."文件超過規定上傳大小";
}
$ext=getExt($filename);
if (!in_array($ext, $allowExt)) {
$res['mes']=$filename.'文件名不合乎規范';
}
if (!is_uploaded_file($temp_name)) {
$res['mes']=$filename."文件不是通過HTTP POST 方法上傳上傳過來的";
}
if (@$res) {
return $res;
}
if (!file_exists($path)) {
mkdir($path,0777,true);
chmod($path, 0777);
}
$fname=getUniName();
$destination=$path.'/'.$fname.'.'.$ext;
if (move_uploaded_file($temp_name, $destination)) {
$res['mes']=$filename.'上傳成功';
$res['dest']=$destination;
}else{
$res['mes']=$filename."文件上傳失敗";
}
}else{
switch ($error) {
case '1':
$res['mes']="超過了配置文件上傳文件的大小";
break;
case '2':
$res['mes']="超過表單設置上傳文件文件的大小";
break;
case '3':
$res['mes']="文件部分被上傳";
break;
case '4':
$res['mes']="沒有文件被上傳";
break;
case '6':
$res['mes']="沒有找到臨時目錄";
break;
case '7':
$res['mes']="文件不可寫";
break;
default:
$res['mes']="上傳文件失敗";
break;
}
}
return $res;
}
其中還涉及了兩個小函數:
/**
* 獲得文件擴展名
* @param string $filename 上傳文件名
* @return string 返回擴展名
*/
function getExt($filename){
$arr=explode('.', basename($filename));
return end($arr);
}
/**
* 獲得文件唯一擴展名
* @return string 經過md5後生成32位唯一的上傳文件名
*/
function getUniName(){
return md5(uniqid(microtime(true),true));
}
感受:
很久前接觸過php文件上傳,當時感覺一團亂麻。現在看來只要掌握$_FILES裡面包含什麼信息,利用自己寫過的知識處理一些小技巧,系統有邏輯的加以考慮,適時地封裝函數,以後文件上傳就可以很快地展開。這次我展現的代碼必然不是能滿足任何需要,所以可以適當改造,成為自己的代碼。比如如果要求上傳文件是圖片內容的話,單靠擴展名是絕對不能判斷的,還需要利用圖片的特性加以驗證。