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

PHP 超全域變數完全指南:從 register_globals 到現代最佳實踐

     編輯:PHP 綜合知識

歷史背景:為什麼需要超全域變數?

PHP 4.2.0 以前,register_globals = On 為預設值。這意味著 ?id=123 會自動建立 $id = 123,Session 變數 $_SESSION['user'] 也能直接用 $user 存取。雖然方便,卻造成嚴重安全隱患:攻擊者可透過 URL 覆蓋內部變數(如 $is_admin=1),導致權限繞過。

PHP 4.2.0 起預設關閉 register_globals,並引入 **超全域變數** 機制:在所有作用域自動可見,無需 global 關鍵字,強制開發者明確指定資料來源。

九大超全域變數詳細對照

超全域變數舊式陣列資料來源典型用途
$_SERVER$HTTP_SERVER_VARSWeb 伺服器環境與執行資訊$_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT'], $_SERVER['REMOTE_ADDR']
$_GET$HTTP_GET_VARSURL 查詢字串參數搜尋關鍵字、分頁頁碼、篩選條件
$_POST$HTTP_POST_VARSHTTP POST 表單欄位登入帳密、文章發布、API 載荷
$_COOKIE$HTTP_COOKIE_VARS客戶端 Cookie記住登入、偏好設定、追蹤 ID
$_SESSION$HTTP_SESSION_VARS伺服器端 Session 儲存用戶身份、購物車、CSRF Token
$_FILES$HTTP_POST_FILESHTTP 檔案上傳頭像上傳、附件處理、文件匯入
$_ENV$HTTP_ENV_VARS系統環境變數部署環境區分、金鑰注入(配合 Docker/K8s)
$_REQUEST—$_GET + $_POST + $_COOKIE(順序受 variables_order 影響)不建議使用,來源模糊易植入惡意資料
$GLOBALS—所有全域變數的參考陣列極少數需動態變數名稱場景

$_FILES 結構深度解析

假設表單欄位 name="myfile":

$_FILES['myfile'] = [
    'name'     => 'photo.jpg',           // 客戶端原始檔名(含路徑資訊,不可信)
    'type'     => 'image/jpeg',          // 瀏覽器回報 MIME,需伺服端二次驗證
    'size'     => 245760,                // 檔案大小(位元組)
    'tmp_name' => '/tmp/phpA1B2C3',      // 伺服器暫存路徑(處理完須 move_uploaded_file 移動)
    'error'    => UPLOAD_ERR_OK          // 錯誤碼:0=成功,1=超過 upload_max_filesize,2=超過 MAX_FILE_SIZE,3=部分上傳,4=無檔案,6=缺少暫存目錄,7=寫入失敗,8=擴展中斷
];

安全處理流程:

  1. 檢查 error === UPLOAD_ERR_OK
  2. 驗證 size 不超業務上限
  3. 使用 finfo_file() 或 mime_content_type() 驗證真實 MIME
  4. 以 move_uploaded_file() 移至非 Web 可執行目錄
  5. 重新命名(UUID + 副檔名),資料庫記錄原始檔名與儲存路徑對應

常見誤區與最佳實踐

❌ 錯誤示範

<?php
// 直接信任 $_SERVER['PHP_SELF'] 導致 XSS
echo '<form action="' . $_SERVER['PHP_SELF'] . '">';

// 使用 $_REQUEST 混淆來源
$id = $_REQUEST['id'];  // 可能來自 Cookie 覆蓋 GET

// 未驗證直接使用 $_FILES
move_uploaded_file($_FILES['f']['tmp_name'], '/var/www/uploads/' . $_FILES['f']['name']);
?>

✅ 正確做法

<?php
// 表單 action 留空或用 htmlspecialchars
echo '<form action="" method="post">';

// 明確來源
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;

// 檔案上傳完整驗證
$allowed = ['image/jpeg', 'image/png', 'image/gif'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime  = finfo_file($finfo, $_FILES['f']['tmp_name']);
if ($_FILES['f']['error'] === UPLOAD_ERR_OK
    && in_array($mime, $allowed)
    && $_FILES['f']['size'] < 2 * 1024 * 1024) {
    $ext = ($mime === 'image/jpeg') ? '.jpg' : (($mime === 'image/png') ? '.png' : '.gif');
    $dest = '/var/www/uploads/' . bin2hex(random_bytes(16)) . $ext;
    move_uploaded_file($_FILES['f']['tmp_name'], $dest);
}
?>

版本演進補充

  • PHP 5.4:移除 register_globals、register_long_arrays($HTTP_*_VARS)、magic_quotes_* 指令。
  • PHP 7.0:$_ENV 預設不再自動填入(需 variables_order 含 E)。
  • PHP 8.1:$_FILES['xxx']['full_path'] 新增完整路徑資訊(目錄上傳)。
核心原則:輸入過濾、輸出轉義、來源明確。超全域變數只是「受管的入口」,安全性取決於你如何驗證與使用這些資料。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved