首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 文件上傳變量差異詳解:$_FILES 與舊版變量的跨平台兼容指南

     編輯:PHP 相關知識

兩套變量體系的由來

PHP 4.1.0 前使用 $HTTP_POST_FILES 及自動全局變量($userfile_name 等);PHP 4.1.0+ 引入超全局陣列 $_FILES,並默認關閉 register_globals。現代代碼**必須使用 $_FILES**。

變量對照表

舊版自動全局變量現代 $_FILES 寫法說明
$userfile_name$_FILES['userfile']['name']客戶端原始文件名
$userfile_tmp_name$_FILES['userfile']['tmp_name']服務器臨時存儲路徑
$userfile_size$_FILES['userfile']['size']文件大小(字節)
$userfile_type$_FILES['userfile']['type']MIME 類型(瀏覽器提供,不可信)
-$_FILES['userfile']['error']上傳錯誤碼(關鍵驗證字段)

跨平台兼容代碼模式

<?php
// 兼容舊代碼的過渡寫法(不推薦長期使用)
$userfile_name = $_FILES['userfile']['name'] ?? '';
$userfile_tmp_name = $_FILES['userfile']['tmp_name'] ?? '';
$userfile_size = $_FILES['userfile']['size'] ?? 0;
$userfile_type = $_FILES['userfile']['type'] ?? '';

// 推薦:直接使用 $_FILES 並封裝處理類
class UploadedFile {
    public string $name;
    public string $tmpPath;
    public int $size;
    public string $mimeType;
    public int $error;

    public static function fromArray(array $file): self {
        $obj = new self();
        $obj->name = $file['name'] ?? '';
        $obj->tmpPath = $file['tmp_name'] ?? '';
        $obj->size = $file['size'] ?? 0;
        $obj->mimeType = $file['type'] ?? '';
        $obj->error = $file['error'] ?? UPLOAD_ERR_NO_FILE;
        return $obj;
    }

    public function isValid(): bool {
        return $this->error === UPLOAD_ERR_OK;
    }

    public function moveTo(string $destination): bool {
        return move_uploaded_file($this->tmpPath, $destination);
    }
}

// 使用示例
$file = UploadedFile::fromArray($_FILES['avatar'] ?? []);
if ($file->isValid()) {
    $ext = pathinfo($file->name, PATHINFO_EXTENSION);
    $newName = bin2hex(random_bytes(16)) . '.' . $ext;
    $file->moveTo("/var/www/uploads/{$newName}");
}
?>

Linux 下常見權限問題排查

  1. 上傳目錄權限:chown www-data:www-data /var/www/uploads && chmod 755 /var/www/uploads
  2. 臨時目錄:php.ini 中 upload_tmp_dir 需可寫,或確保系統 /tmp 可寫
  3. SELinux/AppArmor:可能阻止 httpd 寫入非標準目錄,需設置上下文或調整策略
  4. open_basedir:若啟用,需包含上傳目錄與臨時目錄

安全處理核心原則

  • ✅ 僅信任 $_FILES['file']['tmp_name'] 和 ['size']
  • ✅ 使用 move_uploaded_file() 或 is_uploaded_file() 驗證來源
  • ✅ 重命名存儲(隨機名 + 正確副檔名),防止覆蓋與執行
  • ✅ 校驗 MIME 類型:finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tmpPath)
  • ✅ 限制上傳大小:php.ini + 代碼雙重限制
  • ❌ 絕不信任 ['name']、['type'] 用於業務邏輯
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved