PHP 超全域變數 (Superglobals)

超全域變數是 PHP 預定義的變數,在任何地方都可以存取,不需要使用 global 關鍵字。

超全域變數列表

變數說明
$_GETURL 查詢字串參數
$_POSTPOST 請求資料
$_REQUESTGET + POST + COOKIE
$_FILES上傳的檔案
$_COOKIECookie 資料
$_SESSIONSession 資料
$_SERVER伺服器和執行環境資訊
$_ENV環境變數
$GLOBALS所有全域變數的參考

$_GET

$_GET 用於接收透過 URL 查詢字串傳遞的資料。當使用者在網址後面加上 ?key=value 的參數,PHP 會自動將這些參數放入 $_GET 陣列中。這種方式常用於搜尋功能、分頁、篩選等不敏感資料的傳遞。

<?php
// URL: example.com/page.php?name=Alice&age=25

echo $_GET['name'];  // Alice
echo $_GET['age'];   // 25

// 安全存取
$name = $_GET['name'] ?? 'Guest';
?>

$_POST

$_POST 用於接收透過 HTTP POST 方法提交的表單資料。與 GET 不同,POST 資料不會顯示在網址中,適合傳送密碼、個人資料等敏感資訊。資料大小也沒有 URL 長度的限制。

<?php
// 表單提交後
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = $_POST['name'] ?? '';
    $email = $_POST['email'] ?? '';
}
?>

<form method="POST">
    <input type="text" name="name">
    <input type="email" name="email">
    <button type="submit">送出</button>
</form>

$_SERVER

$_SERVER 包含了伺服器和 HTTP 請求的相關資訊,例如請求方法、使用者 IP、瀏覽器資訊、腳本路徑等。這些資訊由網頁伺服器提供,對於處理請求和除錯非常有用。

<?php
// 常用的 $_SERVER 變數
echo $_SERVER['REQUEST_METHOD'];   // GET 或 POST
echo $_SERVER['REQUEST_URI'];      // /path/to/page.php?query=1
echo $_SERVER['HTTP_HOST'];        // example.com
echo $_SERVER['HTTP_USER_AGENT'];  // 瀏覽器資訊
echo $_SERVER['REMOTE_ADDR'];      // 使用者 IP
echo $_SERVER['DOCUMENT_ROOT'];    // 網站根目錄
echo $_SERVER['SCRIPT_FILENAME'];  // 目前腳本的完整路徑
echo $_SERVER['PHP_SELF'];         // 目前腳本名稱
echo $_SERVER['QUERY_STRING'];     // 查詢字串
?>

$_REQUEST

$_REQUEST 是一個方便的超全域變數,它合併了 $_GET$_POST$_COOKIE 的內容。雖然使用起來方便,但因為無法明確知道資料來源,在安全性考量下,建議直接使用對應的變數。

<?php
// 可以從 GET 或 POST 取得
$action = $_REQUEST['action'] ?? 'default';
?>
建議使用 $_GET$_POST 而非 $_REQUEST,這樣更明確知道資料來源。

$GLOBALS

$GLOBALS 是一個關聯陣列,包含了目前腳本中所有全域變數的參考。透過這個陣列,你可以在函數內存取或修改全域變數,而不需要使用 global 關鍵字。

<?php
$x = 10;
$y = 20;

function test() {
    echo $GLOBALS['x'];      // 10
    echo $GLOBALS['y'];      // 20
    $GLOBALS['z'] = 30;      // 建立新的全域變數
}

test();
echo $z;  // 30
?>

安全處理

<?php
// 驗證和清理輸入
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_GET, 'age', FILTER_VALIDATE_INT);

// 使用 ?? 提供預設值
$page = $_GET['page'] ?? 1;

// 檢查是否存在
if (isset($_POST['submit'])) {
    // 處理表單
}

// 驗證請求方法
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit('Method Not Allowed');
}
?>

實際範例

<?php
// 簡單的頁面路由
$page = $_GET['page'] ?? 'home';

switch ($page) {
    case 'home':
        include 'pages/home.php';
        break;
    case 'about':
        include 'pages/about.php';
        break;
    default:
        http_response_code(404);
        include 'pages/404.php';
}
?>