PHP filter_input() 函数

定义和用法

filter_input() 函数用于从外部环境获取一个变量,并可选地对它进行过滤。

这个函数可以从以下来源获取输入:

  • INPUT_GET - 从 GET 请求获取变量
  • INPUT_POST - 从 POST 请求获取变量
  • INPUT_COOKIE - 从 Cookie 获取变量
  • INPUT_SERVER - 从服务器环境获取变量
  • INPUT_ENV - 从环境变量获取变量
提示:这个函数非常适合用于过滤和验证来自用户输入的数据,提高应用安全性。

语法

filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed

参数值

参数 描述
$type 输入类型。必须是以下常量之一:
  • INPUT_GET
  • INPUT_POST
  • INPUT_COOKIE
  • INPUT_SERVER
  • INPUT_ENV
$variable_name 变量名。要获取的变量的名称
$filter 过滤器类型(可选)。默认为 FILTER_DEFAULT(不进行过滤)。 可以是过滤器 ID(整数)或过滤器常量。
常用过滤器:
  • FILTER_VALIDATE_INT - 验证整数
  • FILTER_VALIDATE_EMAIL - 验证邮箱
  • FILTER_VALIDATE_URL - 验证URL
  • FILTER_SANITIZE_STRING - 去除标签和特殊字符
  • FILTER_SANITIZE_EMAIL - 清理邮箱地址
  • FILTER_SANITIZE_URL - 清理URL
$options 选项/标志(可选)。一个关联数组或一个标志位。
常用选项:
  • FILTER_FLAG_STRIP_LOW - 去除 ASCII 值低于 32 的字符
  • FILTER_FLAG_STRIP_HIGH - 去除 ASCII 值高于 127 的字符
  • FILTER_FLAG_ENCODE_LOW - 编码 ASCII 值低于 32 的字符
  • FILTER_FLAG_ENCODE_HIGH - 编码 ASCII 值高于 127 的字符
  • FILTER_FLAG_ALLOW_FRACTION - 允许浮点数的小数部分
  • FILTER_REQUIRE_SCALAR - 要求输入是标量

返回值

  • 如果成功获取并过滤变量,返回过滤后的值
  • 如果变量不存在,返回 null
  • 如果过滤失败,返回 false
  • 如果未指定过滤器,返回原始值

示例

示例 1:基本用法 - 获取 GET 参数

<?php
// URL: example.com?page=2&name=John

// 获取并验证整型参数
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if ($page !== false && $page !== null) {
    echo "页码: " . $page . "<br>";
} else {
    echo "页码无效或未提供<br>";
}

// 获取并清理字符串参数
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
if ($name !== null) {
    echo "姓名: " . htmlspecialchars($name) . "<br>";
} else {
    echo "姓名未提供<br>";
}
?>

示例 2:处理表单 POST 数据

<?php
// 假设表单提交了以下字段:email, age, website

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 验证邮箱
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if ($email === false) {
        echo "邮箱地址无效<br>";
    } else if ($email === null) {
        echo "邮箱地址未提供<br>";
    } else {
        echo "邮箱地址: " . htmlspecialchars($email) . "<br>";
    }

    // 验证年龄(必须是18-100之间的整数)
    $options = array(
        'options' => array(
            'min_range' => 18,
            'max_range' => 100
        )
    );
    $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $options);
    if ($age === false || $age === null) {
        echo "年龄无效或未提供(必须是18-100之间的整数)<br>";
    } else {
        echo "年龄: " . $age . "<br>";
    }

    // 验证URL
    $website = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL);
    if ($website !== false && $website !== null) {
        echo "网站: " . htmlspecialchars($website) . "<br>";
    } else {
        echo "网站URL无效<br>";
    }
}
?>

示例 3:使用高级选项

<?php
// 清理包含特殊字符的输入
$input = "Hello <script>alert('xss')</script> World!";
// 模拟从POST获取数据
$_POST['comment'] = $input;

// 去除所有HTML标签
$cleaned = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_STRING,
    FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
echo "清理后的评论: " . htmlspecialchars($cleaned) . "<br>";

// 验证IP地址
$ip = "192.168.1.1";
$_GET['ip_address'] = $ip;

// 验证IPv4地址
$valid_ip = filter_input(INPUT_GET, 'ip_address', FILTER_VALIDATE_IP,
    FILTER_FLAG_IPV4);
if ($valid_ip !== false) {
    echo "有效的IPv4地址: " . $valid_ip . "<br>";
} else {
    echo "无效的IP地址<br>";
}
?>

示例 4:获取 COOKIE 和 SERVER 变量

<?php
// 设置一个cookie用于测试
setcookie('user_preference', 'dark_mode', time() + 3600);

// 获取并验证cookie
$theme = filter_input(INPUT_COOKIE, 'user_preference', FILTER_SANITIZE_STRING);
if ($theme !== null) {
    echo "用户主题偏好: " . htmlspecialchars($theme) . "<br>";
} else {
    echo "未设置主题偏好<br>";
}

// 获取服务器信息
$serverName = filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_STRING);
$requestMethod = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING);

echo "服务器名称: " . htmlspecialchars($serverName) . "<br>";
echo "请求方法: " . htmlspecialchars($requestMethod) . "<br>";

// 获取环境变量
$path = filter_input(INPUT_ENV, 'PATH', FILTER_SANITIZE_STRING);
if ($path !== null) {
    echo "PATH环境变量: " . htmlspecialchars(substr($path, 0, 50)) . "...<br>";
}
?>

示例 5:完整表单处理示例

<?php
// 处理用户注册表单
function validateRegistrationForm() {
    $errors = [];
    $data = [];

    // 验证用户名
    $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
    if (empty($username)) {
        $errors['username'] = '用户名不能为空';
    } else if (strlen($username) < 3) {
        $errors['username'] = '用户名至少需要3个字符';
    } else {
        $data['username'] = $username;
    }

    // 验证邮箱
    $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
    if ($email === false || $email === null) {
        $errors['email'] = '请输入有效的邮箱地址';
    } else {
        $data['email'] = $email;
    }

    // 验证年龄
    $ageOptions = [
        'options' => [
            'min_range' => 13,
            'max_range' => 120,
            'default' => 0
        ]
    ];
    $age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, $ageOptions);
    if ($age === 0) {
        $errors['age'] = '年龄必须是13-120之间的整数';
    } else {
        $data['age'] = $age;
    }

    // 验证网站URL(可选)
    $website = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL);
    if ($website !== false && $website !== null) {
        $data['website'] = $website;
    }

    // 验证复选框
    $agreeTerms = filter_input(INPUT_POST, 'agree_terms', FILTER_VALIDATE_BOOLEAN);
    if ($agreeTerms !== true) {
        $errors['agree_terms'] = '必须同意服务条款';
    }

    if (empty($errors)) {
        return ['success' => true, 'data' => $data];
    } else {
        return ['success' => false, 'errors' => $errors];
    }
}

// 如果是POST请求,处理表单
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $result = validateRegistrationForm();
    if ($result['success']) {
        echo "<div class='alert alert-success'>注册成功!</div>";
        echo "<pre>" . print_r($result['data'], true) . "</pre>";
    } else {
        echo "<div class='alert alert-danger'>请修正以下错误:</div>";
        foreach ($result['errors'] as $field => $error) {
            echo "<p>$field: $error</p>";
        }
    }
}
?>

注意事项

  • 变量不存在时返回 null:与直接访问 $_GET['key'] 会报错不同,filter_input() 在变量不存在时返回 null
  • 过滤失败返回 false:当验证失败时,函数返回 false
  • 性能考虑:对于批量处理多个变量,考虑使用 filter_input_array()
  • 默认过滤器:如果不指定过滤器,使用 FILTER_DEFAULT(相当于 FILTER_UNSAFE_RAW
  • 类型转换:验证过滤器(如 FILTER_VALIDATE_INT)会进行类型转换
  • 安全建议:始终对输出到HTML的内容使用 htmlspecialchars() 进行编码

与直接访问超全局数组的比较

方面 filter_input() 直接访问(如 $_GET['key'])
安全性 (内置过滤验证) (需要手动过滤)
变量不存在时 返回 null(不会报错) 可能产生 Notice 错误
代码简洁性 一行代码完成获取和过滤 需要多行代码
验证能力 内置多种验证规则 需要手动实现验证
性能 稍慢(有函数调用开销) 快(直接数组访问)

浏览器支持

该函数是 PHP 后端函数,与浏览器无关。需要 PHP 5.2.0 或更高版本。