PHP 超全局变量:$_GET/$_POST/$_SERVER/$_SESSION 等完全指南

小飞兽 PHP 21 次阅读 2026-07-16

什么是超全局变量

超全局变量是 PHP 内置的预定义变量,在所有作用域(函数、类、文件)中都可以直接访问。它们用于在 Web 请求的不同部分之间传递数据。

一、$_GET — URL 参数

通过 URL 查询字符串传递的数据。

<?php\n// URL: example.com/index.php?name=张三&age=25\necho $_GET['name'];  // 张三\necho $_GET['age'];   // 25\n\n// 安全处理:过滤 + 默认值\n$name = htmlspecialchars($_GET['name'] ?? '');\n$age = (int)($_GET['age'] ?? 0);\n?>

URL 参数的安全问题

<?php\n// 永远不要直接输出用户输入\necho $_GET['name']; // 危险!XSS攻击\n\n// 正确做法:转义\necho htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');\n?>

二、$_POST — POST 表单数据

通过 HTTP POST 方法提交的数据,不会暴露在 URL 中。

<?php\n// HTML表单:<form method="POST" action="submit.php">\n// <input name="username"><input name="password" type="password">\n\n$username = $_POST['username'] ?? '';\n$password = $_POST['password'] ?? '';\n\nif ($username === 'admin' && $password === '123456') {\n    echo '登录成功';\n} else {\n    echo '用户名或密码错误';\n}\n?>

区分 GET 和 POST

<?php\nif ($_SERVER['REQUEST_METHOD'] === 'POST') {\n    // 处理 POST 提交\n    $data = $_POST;\n} else {\n    // 显示表单\n    $data = [];\n}\n?>

三、$_REQUEST — GET + POST 合并

<?php\n// $_REQUEST 同时包含 GET 和 POST 的数据\n// 优先级由 php.ini 的 request_order 决定\necho $_REQUEST['name']; // 不管是 ?name=张三(GET)还是 POST 提交的都能拿到\n\n// 注意:request_order 不包含 cookie 时,$_REQUEST 不包含 $_COOKIE\n// 建议明确用 $_GET 或 $_POST,不用 $_REQUEST\n?>

四、$_SERVER — 服务器信息

包含服务器和执行环境的信息。

<?php\n// 常用 $_SERVER 键\n$_SERVER['REQUEST_METHOD']   // 请求方法:GET/POST/PUT/DELETE\n$_SERVER['REQUEST_URI']      // 请求的 URI:/index.php?page=1\n$_SERVER['QUERY_STRING']     // 查询字符串:page=1\n$_SERVER['HTTP_HOST']        // 主机头:example.com\n$_SERVER['HTTP_USER_AGENT']  // 浏览器标识\n$_SERVER['REMOTE_ADDR']      // 客户端 IP:192.168.1.1\n$_SERVER['SERVER_ADDR']      // 服务器 IP\n$_SERVER['SCRIPT_FILENAME']  // 当前脚本的绝对路径\n$_SERVER['SCRIPT_NAME']      // 当前脚本的路径\n$_SERVER['DOCUMENT_ROOT']    // 网站根目录\n$_SERVER['SERVER_NAME']      // 服务器主机名\n$_SERVER['SERVER_PORT']      // 服务器端口:80/443\n$_SERVER['HTTPS']            // 是否使用 HTTPS:on/off\n$_SERVER['HTTP_REFERER']     // 请求来源页面\n$_SERVER['HTTP_X_REQUESTED_WITH'] // AJAX 请求标识\n\n// 实际应用\n$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';\n$full_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\necho $full_url;  // 完整当前 URL\n\n// 获取客户端 IP(注意代理)\n$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';\n?>

五、$_SESSION — 会话数据

在服务器端存储用户会话数据,跨页面共享。

<?php\n// 开启会话(必须在输出前调用)\nsession_start();\n\n// 存储数据\n$_SESSION['user_id'] = 123;\n$_SESSION['username'] = '张三';\n$_SESSION['is_logged_in'] = true;\n\n// 读取数据\necho $_SESSION['username'];  // 张三\n\n// 检查是否存在\nif (isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in']) {\n    echo '已登录';\n} else {\n    echo '未登录';\n}\n\n// 删除单个键\nunset($_SESSION['username']);\n\n// 销毁所有会话(登出)\nsession_destroy();\n?>

会话配置

<?php\nsession_start([\n    'cookie_lifetime' => 0,        // 浏览器关闭后失效\n    'cookie_secure'   => true,     // 仅 HTTPS 传输\n    'cookie_httponly' => true,     // 禁止 JS 读取(防 XSS)\n    'cookie_samesite' => 'Strict', // CSRF 防护\n    'name'            => 'MY_SESSION',\n]);\n?>

六、$_COOKIE — Cookie 数据

<?php\n// 读取 Cookie\n$theme = $_COOKIE['theme'] ?? 'light';\n$lang = $_COOKIE['language'] ?? 'zh-CN';\n\n// 设置 Cookie(参数:名、值、过期时间、路径、域名、secure、httponly)\nsetcookie('theme', 'dark', time() + 86400 * 30, '/');  // 30天有效期\nsetcookie('token', 'abc123', [\n    'expires'  => time() + 86400 * 7,\n    'path'     => '/',\n    'domain'   => '.example.com',\n    'secure'   => true,\n    'httponly' => true,\n    'samesite' => 'Strict',\n]);\n\n// 删除 Cookie(设置过期时间为过去)\nsetcookie('theme', '', time() - 3600, '/');\n?>

七、$_FILES — 上传文件

<?php\n// HTML: <input type="file" name="avatar">\n\n// $_FILES 结构\n// $_FILES['avatar'] = [\n//     'name'     => 'photo.jpg',      文件原名\n//     'type'     => 'image/jpeg',     MIME类型\n//     'tmp_name' => '/tmp/phpXXXX',   临时文件路径\n//     'error'    => 0,                错误码(0=成功)\n//     'size'     => 123456            文件大小(字节)\n// ]\n\nif ($_SERVER['REQUEST_METHOD'] === 'POST') {\n    $file = $_FILES['avatar'] ?? null;\n\n    if ($file && $file['error'] === UPLOAD_ERR_OK) {\n        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);\n        $newName = bin2hex(random_bytes(16)) . '.' . $ext;\n        $dest = '/var/www/uploads/' . $newName;\n\n        if (move_uploaded_file($file['tmp_name'], $dest)) {\n            echo '上传成功:' . $newName;\n        }\n    } else {\n        echo '上传失败,错误码:' . ($file['error'] ?? '无文件');\n    }\n}\n?>

八、$_ENV — 环境变量

<?php\n// 读取环境变量\necho $_ENV['PATH'] ?? 'not found';\necho getenv('HOME');\n\n// 设置环境变量\nputenv('MY_VAR=hello');\necho getenv('MY_VAR');\n\n// 常用场景:配置数据库密码\n// 在 .env 文件或服务器环境变量中设置,不写在代码里\n$db_password = $_ENV['DB_PASSWORD'] ?? getenv('DB_PASSWORD');\n?>

九、$GLOBALS — 全局变量集合

$GLOBALS 是一个关联数组,包含所有全局作用域的变量。

<?php\n$name = '张三';\n$age = 25;\n\nprint_r($GLOBALS);\n// 包含所有全局变量,包括 $name, $age, $GLOBALS 自身\n\n// 访问全局变量\nfunction test() {\n    echo $GLOBALS['name'];  // 张三,等于 global $name;\n}\n\n// 动态全局变量\n$varname = 'name';\necho $GLOBALS[$varname];  // 张三,等于 $$varname\n?>

十、安全注意事项

    • 永远不相信超全局变量——所有用户输入都是恶意的
    • 输出时转义:htmlspecialchars($_GET['name'])
    • 类型约束:(int)$_GET['id']、(float)$_GET['price']
    • 路径遍历:不要把 $_GET 直接拼进文件路径
    • SQL 注入:永远不要把超全局变量直接拼进 SQL
    • CSRF:敏感操作用 $_SESSION['csrf_token'] 验证
    • Session fixation:登录后执行 session_regenerate_id(true)

    总结

    • $_GET/$_POST 接收用户输入数据,$_REQUEST 是两者合并
    • $_SERVER 包含服务器和请求的元信息
    • $_SESSION 在服务器端存储会话,$_COOKIE 在浏览器端存储
    • $_FILES 专门处理文件上传
    • $GLOBALS 包含所有全局变量,可用于跨函数访问全局变量
  • 所有超全局变量都要验证+过滤后才能使用