Skip to content

特殊变量

1. $_FILES 超全局变量

$_FILES 是 PHP 中用于处理文件上传的超全局数组变量,它包含了通过 HTTP POST 方法上传的所有文件信息。

(1)基本结构

当表单使用 enctype="multipart/form-data" 并且有文件上传字段时,$_FILES 数组会包含如下结构的元素:

php
$_FILES = [
    'input_name' => [
        'name' => 'filename.ext',     // 原始文件名
        'type' => 'mime/type',       // 文件 MIME 类型
        'tmp_name' => '/tmp/phpXxXxX', // 服务器上的临时文件路径
        'error' => 0,                // 错误代码(0表示无错误)
        'size' => 12345              // 文件大小(字节)
    ]
];

各字段说明

  1. name

    • 客户端上传文件的原始名称
    • 示例: 'example.jpg'
  2. type

    • 浏览器提供的 MIME 类型
    • 示例: 'image/jpeg'
    • 注意: 此值可以被伪造,不应单独用于验证
  3. tmp_name

    • 文件上传后在服务器上的临时存储路径
    • 示例: '/tmp/php5D.tmp'
  4. error

    • 错误代码(整型),常见值:
      • UPLOAD_ERR_OK (0) - 无错误
      • UPLOAD_ERR_INI_SIZE (1) - 超过 php.ini 中的大小限制
      • UPLOAD_ERR_FORM_SIZE (2) - 超过表单中 MAX_FILE_SIZE 限制
      • UPLOAD_ERR_PARTIAL (3) - 文件只有部分被上传
      • UPLOAD_ERR_NO_FILE (4) - 没有文件被上传
      • UPLOAD_ERR_NO_TMP_DIR (6) - 找不到临时文件夹
      • UPLOAD_ERR_CANT_WRITE (7) - 写入磁盘失败
      • UPLOAD_ERR_EXTENSION (8) - PHP 扩展阻止了上传
  5. size

    • 上传文件的大小(字节)
    • 示例: 102400 (100KB)

(2)使用示例

基本文件上传处理

php
if ($_FILES['userfile']['error'] === UPLOAD_ERR_OK) {
    $tmp_name = $_FILES['userfile']['tmp_name'];
    $name = basename($_FILES['userfile']['name']);
    move_uploaded_file($tmp_name, "/uploads/$name");
}

多文件上传处理

当使用多文件上传(如 <input type="file" name="files[]" multiple>)时:

php
foreach ($_FILES['files']['error'] as $key => $error) {
    if ($error === UPLOAD_ERR_OK) {
        $tmp_name = $_FILES['files']['tmp_name'][$key];
        $name = basename($_FILES['files']['name'][$key]);
        move_uploaded_file($tmp_name, "/uploads/$name");
    }
}

(3)安全注意事项

  1. 永远不要信任 $_FILES['...']['name']

    • 客户端可以发送任意文件名,包括恶意路径如 ../../../etc/passwd
  2. 验证文件内容

    • 不要依赖 $_FILES['...']['type'],因为它可以被伪造
    • 使用 finfo_file() 或文件头检查实际文件类型
  3. 使用 move_uploaded_file()

    • 此函数会额外检查文件是否是通过 HTTP POST 上传的
  4. 设置合理限制

    • 在 php.ini 中配置:
      ini
      upload_max_filesize = 2M
      post_max_size = 3M
  5. 处理错误

    • 总是检查 $_FILES['...']['error'] 的值

(4)完整安全示例

php
$upload_dir = '/path/to/safe/directory/';
$allowed_types = ['image/jpeg', 'image/png'];
$max_size = 1024 * 1024; // 1MB

if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
    die("上传错误: " . $_FILES['file']['error']);
}

// 验证文件类型
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
finfo_close($finfo);

if (!in_array($mime, $allowed_types)) {
    die("不允许的文件类型");
}

// 验证文件大小
if ($_FILES['file']['size'] > $max_size) {
    die("文件太大");
}

// 生成安全文件名
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$filename = uniqid() . '.' . $ext;

// 移动文件
if (!move_uploaded_file(
    $_FILES['file']['tmp_name'],
    $upload_dir . $filename
)) {
    die("文件保存失败");
}

echo "文件上传成功!";

2.$_SERVER 超全局变量详解

$_SERVER 是 PHP 中一个非常重要的超全局变量,它包含了服务器和执行环境的信息。这些信息包括头部信息(header)、路径(path)和脚本位置(script locations)等。

(1)基本介绍

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等信息的数组。这个数组中的项目由 Web 服务器创建。

(2)常用 $_SERVER 元素

服务器信息

  • $_SERVER['SERVER_NAME'] - 当前运行脚本所在的服务器的主机名
  • $_SERVER['SERVER_SOFTWARE'] - 服务器标识字符串
  • $_SERVER['SERVER_PROTOCOL'] - 请求页面时通信协议的名称和版本
  • $_SERVER['SERVER_ADDR'] - 服务器 IP 地址
  • $_SERVER['SERVER_PORT'] - 服务器使用的端口

请求信息

  • $_SERVER['REQUEST_METHOD'] - 访问页面使用的请求方法(如 GET、POST 等)
  • $_SERVER['REQUEST_URI'] - URI 用来指定要访问的页面
  • $_SERVER['QUERY_STRING'] - 查询字符串(URL 中第一个问号 ? 之后的内容)
  • $_SERVER['HTTP_REFERER'] - 引导用户代理到当前页的前一页的地址
  • $_SERVER['HTTP_USER_AGENT'] - 用户代理字符串(浏览器信息)
  • $_SERVER['REMOTE_ADDR'] - 浏览当前页面的用户的 IP 地址
  • $_SERVER['REMOTE_PORT'] - 用户机器上连接到 Web 服务器所使用的端口号

脚本信息

  • $_SERVER['SCRIPT_FILENAME'] - 当前执行脚本的绝对路径
  • $_SERVER['SCRIPT_NAME'] - 包含当前脚本的路径
  • $_SERVER['PHP_SELF'] - 当前执行脚本的文件名
  • $_SERVER['DOCUMENT_ROOT'] - 当前运行脚本所在的文档根目录

(3)使用示例

php
<?php
// 获取客户端IP地址
$ip = $_SERVER['REMOTE_ADDR'];

// 获取当前页面的完整URL
$url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

// 获取用户浏览器信息
$browser = $_SERVER['HTTP_USER_AGENT'];

// 获取请求方法
$method = $_SERVER['REQUEST_METHOD'];

// 获取引荐来源(如果有)
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '直接访问';

echo "IP地址: $ip <br>";
echo "当前URL: $url <br>";
echo "浏览器: $browser <br>";
echo "请求方法: $method <br>";
echo "来源: $referer <br>";
?>

(4)注意事项

  1. 不是所有的 $_SERVER 元素在所有服务器上都可用,有些元素依赖于特定的服务器配置。

  2. $_SERVER 中的 HTTP_ 开头的元素(如 HTTP_REFERER)是由客户端发送的,可以被伪造,不应完全信任。

  3. 某些元素如 PHP_SELF 可能包含用户输入,直接使用可能导致 XSS 攻击,应该先过滤:

    php
    $php_self = htmlspecialchars($_SERVER['PHP_SELF']);
  4. 在命令行模式下运行 PHP 时,$_SERVER 的内容与在 Web 服务器环境下有很大不同。

  5. 某些服务器变量在不同服务器(Apache、Nginx、IIS等)上可能有不同的名称或行为。

$_SERVER 是一个非常有用的变量,特别是在需要获取环境信息或处理 URL 时,但使用时应当注意安全性和跨服务器的兼容性问题。

滇ICP备2025057983号-1