PHP關於文件$_FILES一些問題、校驗和限制

科學研究

通過 PHP,可以把文件上傳到服務器。通過$_FILES可以獲取文件上傳的相關信息;從而對文件進行操作。經過我的科學研究,發明了許多奇奇怪怪的問題;經過我的認真思考,終於;還是沒能解決。最後一邊百度一邊思考。

上傳單個文件

  1. 不管三七二十一,涉及到上傳文件都需要使用enctype="multipart/form-data"進行編碼
  2. 我們可以使用accept設置文件上傳的類型,然並卵,設置了用戶還是能更改,所以需要php驗證(接收兩種值MINE TYPE和文件擴展名)
  3. 我們驗證表單的時候可以使用isset吞掉Undefined index的警告
  4. 使用$_FILES[‘name’]獲取上傳文件的信息
  5. 如果是提交到本頁面,使用$_SERVER['PHP_SELF']提高代碼的魯棒性
<?php if($_SERVER['REQUEST_METHOD']==='POST'){ echo '1111'; var_dump($_FILES['file']); } ?>
...
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="source">文件</label>
        <input type="file" name="file" accept="image/*">
    </div>
    <button>保存</button>
</form>
  • 我這裏選擇了一張圖片上傳
  • 結果打印的圖片信息是一個關聯數組,右邊的值是string類型,所以我們操作的時候不用再遍歷數組
    結果
  • 上面各個參數的意思
$_FILES["file"]["name"] - 上傳文件的名稱
$_FILES["file"]["type"] - 上傳文件的類型
$_FILES["file"]["size"] - 上傳文件的大小,以字節計
$_FILES["file"]["tmp_name"] - 存儲在服務器的文件的臨時副本的名稱(這裏使用的是wampserver服務器,所以是wamp臨時文件夾,打開該文件夾,可以看到會有一個文件生成然後就清除了)
$_FILES["file"]["error"] - 由文件上傳導致的錯誤代碼

type

  • 這裏我們可以校驗文件的類型
$file = $_FILES['file'];
        if(strpos($file['type'],'image/')!==0){
            echo '文件不爲圖片類型';
        }

size

  • 我們可以限制上傳圖片的大小,比如圖片不能大於1M
if ($file['size'] > 1 * 1024 * 1024) {
      echo '上傳文件過大';
      return;
}

name和tmp_name

  1. 一般我們用來移動文件,會用到文件名和臨時文件夾
  2. 有時候我們發現在移動文件名的時候,如果文件存在中文名,會移動失敗,所以我們需要注意中文的問題
  3. 使用move_uploaded_file移動文件
  4. 有時候我們沒有創建文件夾的話,需要使用(file_exists檢測文件夾)
// 1. 移動到我們網站根目錄下uploads文件夾下,爲了防止重名,使用產生uniqid隨機數
        $tmp = $file['tmp_name'];
        $target = './uploads/'.uniqid().$file['name'];
        $moved = move_uploaded_file($tmp,$target);
  1. 中文文件問題解決iconv('UTF-8', 'GBK', $file['name']

error的情況

  • UPLOAD_ERR_OK
    值爲 0:沒有錯誤發生,文件上傳成功
  • UPLOAD_ERR_INI_SIZE
    值爲 1:上傳的文件超過了 php.ini中upload_max_filesize(默認情況爲2M) 選項限制的值
  • UPLOAD_ERR_FORM_SIZE
    值爲 2:上傳文件的大小超過了 HTML表單中MAX_FILE_SIZE選項指定的值
  • UPLOAD_ERR_PARTIAL
    值爲 3:文件只有部分被上傳
  • UPLOAD_ERR_NO_FILE
    值爲 4:沒有文件被上傳
  • 值爲5,傳文件大小爲0;文件爲0基本不會報這個錯誤
  • UPLOAD_ERR_NO_TMP_DIR
    值爲 6,找不到臨時文件夾。PHP 4.3.10 和 PHP 5.0.3 引進。
  • UPLOAD_ERR_CANT_WRITE
    值爲 7,文件寫入失敗。PHP 5.1.0 引進。

很多時候我們都會報錯1,或則有時候發現文件移動不了,除了中文問題,基本是後臺進行了設置。
我移動圖片基本沒問題,但移動音樂文件時就報了1這個錯誤;後來我做了多次臨牀試驗…
發現是文件太大導致移動不成功;我查看了文檔修改了php限制問題
我這裏使用的是wampserver服務器,所以我找到wamp\bin\php\php5.4.12下的php.ini

file_uploads = on ;是否允許通過HTTP上傳文件的開關。默認爲ON即是開
upload_tmp_dir ;文件上傳至服務器上存儲臨時文件的地方,如果沒指定就會用系統默認的臨時文件夾
file_uploads = on ;是否允許通過HTTP上傳文件的開關。默認爲ON即是開
upload_tmp_dir ;文件上傳至服務器上存儲臨時文件的地方,如果沒指定就會用系統默認的臨時文件夾

然而還是沒有成功,我轉頭一想,這是服務器的問題,應該是該Apache下的php.ini,所以我找到了wamp\bin\apache\Apache2.4.4\bin下的php.ini;最好試驗成功了
如果在不行,可以在進一步配置

max_execution_time = 600 ;每個PHP頁面運行的最大時間值(),默認30秒
max_input_time = 600 ;每個PHP頁面接收數據所需的最大時間,默認60秒
memory_limit = 8m ;每個PHP頁面所吃掉的最大內存,默認8M

當然文件上傳失敗我們也需要做處理

if ($file['error'] !== UPLOAD_ERR_OK) {
            echo '文件上傳失敗';
            return;
        }

上傳成功在移動文件

上傳多個文件

使用multiple上傳多個文件;在name值裏面加上[]來接收多個文件

<input type="file" name="image[]" accept="image/*" multiple>

結果打印var_dump($_FILES['image']);的結果是不一樣
結果
我們獲取關聯數組,右邊的值是一個數組,所以我們需要在進行遍歷,跟單個文件獲取是不一樣結果

參考文檔

isset 和 empty
PHP文件上傳