PHP 超全局变量:$_GET/$_POST/$_SERVER/$_SESSION 等完全指南
什么是超全局变量
超全局变量是 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包含所有全局变量,可用于跨函数访问全局变量- 所有超全局变量都要验证+过滤后才能使用