PHP檔案上傳原理詳解(附源碼)
PHP檔案上傳原理詳解(附源碼)
1、檔案上傳原理
將用戶端的檔案上傳到伺服器,再將伺服器的臨時檔案上傳到指定目錄
2、用戶端配置
- 提交表單
- 表單的發送方式為post
- 添加enctype="multipart/form-data"
3、伺服器端配置
- file_uploads = On,支援HTTP上傳
- uoload_tmp_dir = ,臨時檔案儲存目錄
- upload_max_filesize = 2M,允許上傳檔案的最大值
- max_file_uploads = 20 ,允許一次上傳到的最大檔案數
- post_max_size = 8M,post方式發送資料的最大值
- max_execution_time = -1,設定了指令碼被解析器終止之前允許的最大執行時間,單位為秒,防止程式寫的不好而佔盡伺服器資源。-1代表無窮
- max_input_time = 60 ,指令碼解析輸入資料允許的最大時間,單位為秒
- max_input_nesting_level = 64 ,設定輸入變數的嵌套深度
- max_input_vars_ = 1000,接受多少輸入的變數(限制分別應用於$_GET、$_POST和$_COOKIE超全域變數,將會導致E_WARNING的產生,更多的輸入變數將會從請求中截斷。
- memory_limit = 128M,最大單線程的獨立記憶體使用量量。也就是一個web請求,給予線程最大的記憶體使用量量的定義
4、錯誤資訊說明
- UPLOAD_ERR_OK:其值為0,沒有錯誤發生,檔案上傳成功
- UPLOAD_ERR_INI_SIZE:其值為1,上傳的檔案超過了php.ini中upload_max_filesize選項限制的值
- UPLOAD_ERR_FORM_SIZE:其值為2,上傳檔案的大小超過了HTML表單中MAX_FILE_SIZE選項指定的值
- UPLOAD_ERR_PARTIAL:其值為3,檔案只有部分被上傳
- UPLOAD_ERR_NO_FILE:其值為4,沒有檔案被上傳
- UPLOAD_ERR_NO_TMP_DIR:其值為6,找不到臨時檔案夾
- UPLOAD_ERR_CANT_WRITE:其值為7,檔案寫入失敗
- UPLOAD_ERR_EXTENSION:其值為8,上傳的檔案被PHP擴充程式中斷
5、用戶端限制
6、在用戶端的限制,使用者可在網頁上修改代碼後上傳,故無實際意義。應在伺服器端加以限制
- 限制上傳檔案的大小
- 限制上傳檔案類型
- 檢測是否為真實圖片類型
- 檢測是否為HTTP POST方式上傳
7、完整代碼如下:
upload.php
<!DOCTYPE html>
<html>
<head>
<title>檔案上傳www.bkjia.com</title>
<meta charset="utf-8">
</head>
<body>
<form action="test.php" method="post" enctype="multipart/form-data" >
請選擇要上傳的檔案:
<input type="file" name="myFile" /><br />
<input type="submit" value="上傳檔案" />
</form>
</body>
</html>
test.php
<?php
header('content-type:text/html;charset=utf-8');
include_once 'upload.func.php';
//上傳封裝函數的五個參數:$fileInfo,$maxsize,$uploadPath,$allowExt,$flag
$fileInfo=$_FILES['myFile'];
// print_r($_FILES);
// exit;
// $filename=$_FILES['myFile']['name'];
// $type=$_FILES['myFile']['type'];
// $tmp_name=$_FILES['myFile']['tmp_name'];
// $size=$_FILES['myFile']['size'];
// $error=$_FILES['myFile']['error'];
$maxsize=2097152;
$uploadPath='uploads';
$allowExt=array('jpeg','jpg','png','gif');
$flag=true;
$newName=uploadFile($fileInfo,$maxsize,$uploadPath,$allowExt,$flag);
echo "上傳成功,路徑為:".$newName;
?>
upload.func.php
<?php
function uploadFile($fileInfo,$maxsize,$uploadPath,$allowExt,$flag){
//判斷錯誤號碼
if($fileInfo['error']>0){
switch ($fileInfo['error']){
case '1':
$mes="上傳檔案超過了PHP設定檔中upload_max_filesize選項的值";
break;
case '2':
$mes="超過了表單MAX_FILE_SIZE限制的大小";
break;
case '3':
$mes="檔案部分被上傳";
break;
case '4':
$mes="沒有選擇上傳檔案";
break;
case '6':
$mes="沒有找到臨時目錄";
break;
case '7':
case '8':
$mes="系統錯誤";
break;
}
exit($mes);
}
$ext=pathinfo($fileInfo['name'],PATHINFO_EXTENSION);
//檢測上傳檔案的類型
if (!@in_array($ext,$allowExt)) {
exit('非法檔案類型');
}
//檢測上傳檔案的大小是否符合規範
//$maxsize=2097152;//預設值為2M
if ($fileInfo['size']>$maxsize) {
exit('上傳檔案超過'.($maxsize/1024/1024).'M');
}
//檢測圖片是否為真實圖片類型,立flag,若不需要檢測,則設定flag為false即可
//$flag=true;
if($flag){
if (!@getimagesize($fileInfo['tmp_name'])) {
exit('不是真實的圖片類型');
}
}
//檢測檔案是否通過HTTP POST方式上傳的
if (!@is_uploaded_file($fileInfo['tmp_name'])) {
exit('檔案不是通過HTTP POST方式上傳的');
}
//儲存目錄
if(!@file_exists($uploadPath)){
mkdir($uploadPath,0777,true);
chmod($uploadPath,0777);
}
$uniName=MD5(uniqid(microtime(true),true)).'.'.$ext;
$destination=$uploadPath.'/'.$uniName;
if (!@move_uploaded_file($fileInfo['tmp_name'], $destination)) {
exit('檔案上傳失敗');
}
//echo "檔案上傳成功";
// return array{
// 'newName'=>$destination;
// 'size'=>$fileInfo['size'];
// 'type'=>$fileInfo['type']
// };
return $destination;
}
?>