PHP上傳原理及操作實現

PHP上傳原理及操作實現

關於PHP上傳文件的函數類庫,網上有許多封裝很完善,大家直接拿來用就可以。

本文章只是說下關於上傳原理和簡單的上傳操作,老鳥就無視了哈^_^~

還有一些安全性判斷比如:服務端限制能接收圖片類型的文件,而客戶端惡意將病毒文件的後綴名改爲圖片配型的文件上傳。

 

(舉例單文件上傳,多文件原理還是不變,只不過多了點小技巧)

 

index.html

複製代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>upload files</title>
</head>
<body>

    <form action="upload.php" enctype="multipart/form-data" method="post">
        <input type="hidden" name="MAX_FILE_SIZE" value="10000" />
        上傳文件:<input type="file" name="file"/>
        <input type="submit" value="上傳" />
    </form>
</body>
</html>

複製代碼

1、Form標籤enctype屬性

表單中enctype="multipart/form-data"是用於設置表單的MIME編碼。
默認情況,這個編碼格式是application/x-www-form-urlencoded,不能用於文件上傳;
只有使用了multipart/form-data且提交方式爲Post才能完整的傳遞文件數據。

 

2、MAX_FILE_SIZE 隱藏字段

MAX_FILE_SIZE 隱藏字段(單位爲字節)必須放在文件輸入字段之前,其值爲接收文件的最大尺寸。這是對瀏覽器的一個建議,PHP 也會檢查此項。
在瀏覽器端可以簡單繞過此設置,因此不要指望用此特性來阻擋大文件。(不過鑑於友好性最好還是在表單中加上此項目,因爲它可以避免用戶在花時間等待上傳大文件之後才發現文件過大上傳失敗的麻煩。)

 

upload.php

<?php    
    print_r($_FILES);
?>

我們可以看到:

複製代碼

Array
(
    [file] => Array
        (
            [name] => 照片文件.jpg
            [type] => image/jpeg
            [tmp_name] => F:\wamp\tmp\php41BB.tmp
            [error] => 0
            [size] => 73886
        )

)

複製代碼

 

3、全局變量 $_FILES的應用

  $_FILES['file']['name']  爲上傳文件的原文件名

  $_FILES['file']['type']  爲上傳文件的 MIME 類型

  $_FILES['file']['size']  已上傳文件的大小,單位爲字節

  $_FILES['file']['tmp_name']  文件被上傳後在服務端儲存的臨時文件名()

  $_FILES['file']['error']  文件上傳的錯誤代碼

 

4、默認情況下,上傳文件會保存在服務端的臨時文件夾中,其目錄在php.ini中設置

php.ini與文件上傳有關的一些常用設置:

file_uploads ;  是否允許通過HTTP上傳文件的開關。默認爲ON即是開

upload_tmp_dir ;  文件上傳至服務器上存儲臨時文件的地方,如果沒指定就會用系統默認的臨時文件夾

upload_max_filesize;  即允許上傳文件大小的最大值。默認爲2M

post_max_size;  指通過表單POST給PHP的所能接收的最大值,包括表單裏的所有值。默認爲8M

 

下面是對單文件上傳的完整代碼,因爲是隨想隨寫的,可能邏輯嵌套的有點亂,懂原理最重要。

複製代碼

<?php
    
    //取得上傳文件信息
    $fileName=$_FILES['file']['name'];
    $fileType=$_FILES['file']['type'];
    $fileError=$_FILES['file']['error'];
    $fileSize=$_FILES['file']['size'];
    $tempName=$_FILES['file']['tmp_name'];//臨時文件名
    
    //定義上傳文件類型
    $typeList = array("image/jpeg","image/jpg","image/png","image/gif"); //定義允許的類型

    if($fileError>0){
            //上傳文件錯誤編號判斷
            switch ($fileError) {
                case 1:
                    $message="上傳的文件超過了php.ini 中 upload_max_filesize 選項限制的值。"; 
                    break;
                case 2:
                    $message="上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。"; 
                    break;
                case 3:
                    $message="文件只有部分被上傳。"; 
                    break;
                case 4:
                    $message="沒有文件被上傳。";
                    break;
                case 6:
                    $message="找不到臨時文件夾。"; 
                    break;
                case 7:
                    $message="文件寫入失敗"; 
                    break;
                case 8:
                    $message="由於PHP的擴展程序中斷了文件上傳";
                    break;
            }

            exit("文件上傳失敗:".$message);

        }
    if(!is_uploaded_file($tempName)){
        //判斷是否是POST上傳過來的文件
        exit("不是通過HTTP POST方式上傳上來的");
    }else{
        if(!in_array($fileType, $typeList)){
            exit("上傳的文件不是指定類型");
        }else{
            if(!getimagesize($tempName)){
                //避免用戶上傳惡意文件,如把病毒文件擴展名改爲圖片格式
                exit("上傳的文件不是圖片");
            }
        }
            if($fileSize>100000){
                //對特定表單的上傳文件限制大小
                exit("上傳文件超出限制大小");
            }else{
                //避免上傳文件的中文名亂碼
                $fileName=iconv("UTF-8", "GBK", $fileName);//把iconv抓取到的字符編碼從utf-8轉爲gbk輸出
                $fileName=str_replace(".", time().".", $fileName);//在圖片名稱後加入時間戳,避免重名文件覆蓋
                if(move_uploaded_file($tempName, "uploads/".$fileName)){
                    echo "上傳文件成功!";
                }else{
                    echo "上傳文件失敗";
                }
            }

        }

?>

複製代碼

 

5、關於php上傳文件的一些常用函數:(具體用法就不貼出來了,自己看API文檔吧 ^_^)

file_exists  檢查文件或目錄是否存在

is_uploaded_file    判斷文件是否是通過 HTTP POST 上傳的

move_uploaded_file    將上傳的文件移動到新位置

is_writable   判斷給定的文件名是否可寫

iconv  字符編碼互轉

str_replace  字符串替換(更改文件名,防重名)

getimagesize  檢查是否爲圖片文件(其他類型的文件就算後綴名改了也能被檢測到)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章