PHP的filter扩展详解

来源:互联网 发布:纽约客插画知乎 编辑:程序博客网 时间:2024/04/28 08:25
大概浏览下PHP手册,发现在 "函数参考->变量与类型相关扩展" 中有个Filter扩展,然后又在网上找了几篇博客看了看,都是10年左右的文章,实在不知道这个技术是否实用,一直在纠结,想想算了,就当花时间提高英文了:

https://www.gracecode.com/posts/3029.html的博客,提到了国外的一篇文章,我就翻译下吧。

原文地址:

Never Use $_GET Again

我的翻译地址:

别再使用$_GET了


现在开始filter模块介绍(基本就是过了一遍手册,总结的):

简介:

    filter扩展过滤数据通过验证和安全化2种方式。当数据源包含不知道的数据,正如用户提供的输入数据,使用filter扩展是非常有用的。例如:数据来自html表单提交。
    有2类主要的过滤器:验证和安全化
    验证(validation):如果数据需要满足特定条件,则用于验证或检查。例如:传入 'FILTER_VALIDATE_EMAIL',将检测数据是否是一个有效的email地址,但并不会改变数据本身。
    安全化(sanitization):使数据安全化,因此它可能通过删除不期望的字符来修改数据。例如:传入'FILTER_SANITIZE_EMAIL',将删除email地址之外的其他字符。也就是说,它不会验证数据。
    使用验证和安全化时,根据需求,可选的flags被用于调整行为。例如:当过滤一个URL时,传入 'FILTER_FLAG_PATH_REQUIRED',将引入当前的一个路径(就像:/foo in http://example.org/foo)

安装:

    过滤器扩展,在5.2.0以后默认开启。5.2.0之前使用一个试验性的 'PECL' 扩展,这个扩展不再推荐和更新了。
运行时配置,有2个配置:
    filter.default - 默认值是:unsafe_raw
    filter.default_flags - 默认值是:NULL


    1.filter.default - string类型
        过滤所有的$_GET, $_POST, $_COOKIE, $_REQUEST 和 $_SERVRE数据。可以通过 filter_input() 来访问原始数据。
        默认情况下,接收你喜欢使用的过滤器的名字,查看存在的 "过滤器列表"。
        注意:
            小心默认过滤器的默认标志(flag),你应该准确的设置过滤器的标志为你想要的值。例如:为了配置默认过滤器表现的同htmlspecialchars()完全一样,你需要设置过滤器的默认标志为0,就像下面展示的这样:
            filter.default = full_special_chars
            filter.default_flags = 0
    2.filter.default_flags - integer类型
        设置过滤器的标志。默认情况下,该配置被设置为 'FILTER_FLAG_NO_ENCODE_QUOTES',为了向后兼容。查看所有的 'flag列表' 
    3.过滤器列表和过滤器标志,可查看手册,有点多,暂不统计

过滤器函数:


    函数简介:
        1.filter_list() - 获取所支持的过滤器列表
        2.filter_id(string $filtername) - 传入过滤器名称,可得到过滤器的id(常量定义)
        3.filter_has_var(int $type, string $variable_name) - 假设$type = INPUT_GET,表示:从$_GET中查找的变量是否存在,例如:$_GET['name']是否存在
        4.filter_input(int $type, string $variable_namme[, int $filter = FILTER_DEFAULT[, mixed $options]]) - $_GET['name']存在后,我们可给它设置过滤器和一些options配置,来过滤变量。
        5.filter_input_array(int $type[, mixed $definition[, bool $add_empty = true]]) - 同上,只不过针对的是多个变量,批量配置。例如:$_GET['name'], $_GET['password']
        6.filter_var(mixed $variable[, int $filter = FILTER_DEFAULT[, mixed $options]])
        7.filter_var_array(array $data[, mixed $definition[, bool $add_empty = true]])
            这2个的作用,和filter_input()与filter_input_array()非常类似,只不过可真对所有变量,包括我们自定义的变量过滤。也可直接:
            $filter_var($_GET['name']) === $filter_input(INPUT_GET, 'name')
            $filter_var($name)  // $name = 'dongxuemin',我们自定义的变量,而不是从用户输入中获取的

函数详情:


    filter_list()
        返回所支持的过滤器列表
        1.返回值
            返回一个所支持的过滤器的名称的列表,如果没有这样子的过滤器的话则返回空数组。这个数组的索引不是过滤器id, 你可以通过 filter_id() 去根据名称获取它们。


    filter_id(string $filtername)
        返回某个特定名称的过滤器相关联的id(不就是过滤器名称代表的常量值吗?)
        1.$filtername
            待获取的过滤器名称
        2.返回值
            如果获取成功则返回过滤器id,如果过滤器不存在,则返回false


    filter_has_var(int $type, string $variable_name)
        检测指定类型中,变量是否存在。
        1.$type
            INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER 或 INPUT_ENV中的一个
        2.$variable_name
            要检查的变量名
        3.返回值
            成功时,返回true,失败时,返回false


    filter_input(int $type, string $variable_namme[, int $filter = FILTER_DEFAULT[, mixed $options]])
        通过名称获取特定的外部变量,并且可以通过过滤器处理它
        1.$type
            INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER 或 INPUT_ENV中的一个
        2.$variable_name
            待获取的变量名
        3.$filter
            要应用的过滤器id。如果省略,将使用 'FILTER_DEFAULT',就是 'FILTER_UNSAFE_RAW'。默认情况下,这将导致未发生过滤。
        4.$options
            一个选项的关联数组,或者按位区分的标示。如果过滤器接受选项,可以通过数组的 "flags" 位去提供这些标示。 对于回调型的过滤器,应该传入 callable。这个回调函数必须接受一个参数,即待过滤的值,并且 返回一个在过滤/净化后的值。
        5.返回值,注意下面3种情况返回的返回值:
            1>如果成功的话返回所请求的变量。
            2>如果过滤失败则返回 FALSE ,如果variable_name 不存在的话则返回 NULL 。 
            3>如果标示 FILTER_NULL_ON_FAILURE 被使用了,那么当变量不存在时返回 FALSE ,当过滤失败时返回 NULL 。


    filter_input_array(int $type[, mixed $definition[, bool $add_empty = true]]) 
        获取一系列外部变量,并且可以通过过滤器处理它们。这个函数当需要获取很多变量却不想重复调用filter_input()时很有用。
        1.$type
            INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER 或 INPUT_ENV中的一个
        2.$definition
            一个定义参数的数组。一个有效的键必须是一个包含变量名的string,一个有效的值要么是一个filter type,或者是一个array 指明了过滤器、标示和选项。如果值是一个数组,那么它的有效的键可以是 filter, 用于指明 filter type,flags 用于指明任何想要用于过滤器的标示,或者 options 用于指明任何想要用于过滤器的选项。 参考下面的例子来更好的理解这段说明。
            这个参数也可以是一个filter constant的整数。那么数组中的所有值都会被这个过滤器所过滤。
        3.$add_empty
            在返回值中添加 NULL 作为不存在的键。


    filter_var(mixed $variable[, int $filter = FILTER_DEFAULT[, mixed $options]])
        使用特定的过滤器过滤一个变量
        1.$variable
            待过滤的变量
        2.$filter
            要应用的过滤器id。如果省略,将使用 'FILTER_DEFAULT',就是 'FILTER_UNSAFE_RAW'。默认情况下,这将导致未发生过滤。
        3.$options
            一个选项的关联数组,或者按位区分的标示。如果过滤器接受选项,可以通过数组的 "flags" 位去提供这些标示。 对于回调型的过滤器,应该传入 callable。这个回调函数必须接受一个参数,即待过滤的值,并且 返回一个在过滤/净化后的值。
        4.返回值
            返回过滤后的数据,如果过滤失败,返回false。


    filter_var_array(array $data[, mixed $definition[, bool $add_empty = true]])
        获取多个变量,并且过滤它们
        1.$data
            一个键为字符串,值为待过滤的数据的数组。
        2.$definition
            一个定义参数的数组。一个有效的键必须是一个包含变量名的string,一个有效的值要么是一个filter type,或者是一个array 指明了过滤器、标示和选项。如果值是一个数组,那么它的有效的键可以是 filter, 用于指明 filter type,flags 用于指明任何想要用于过滤器的标示,或者 options 用于指明任何想要用于过滤器的选项。 参考下面的例子来更好的理解这段说明。
            这个参数也可以是一个filter constant的整数。那么数组中的所有值都会被这个过滤器所过滤。
        3.$add_empty
            在返回值中添加 NULL 作为不存在的键。

测试实例:

    1.filter_list()&filter_id()
    <?php        echo "<pre>";        print_r($list = filter_list());        echo "</pre>";        foreach($list as $filter){            echo "<p>$filter=".filter_id($filter)."</p>";        }    ?>

    输出:
    Array    (        [0] => int        [1] => boolean        [2] => float        [3] => validate_regexp        [4] => validate_domain        [5] => validate_url        [6] => validate_email        [7] => validate_ip        [8] => validate_mac        [9] => string        [10] => stripped        [11] => encoded        [12] => special_chars        [13] => full_special_chars        [14] => unsafe_raw        [15] => email        [16] => url        [17] => number_int        [18] => number_float        [19] => magic_quotes        [20] => callback    )    int=257    boolean=258    float=259    validate_regexp=272    validate_domain=277    validate_url=273    validate_email=274    validate_ip=275    validate_mac=276    string=513    stripped=513    encoded=514    special_chars=515    full_special_chars=522    unsafe_raw=516    email=517    url=518    number_int=519    number_float=520    magic_quotes=521    callback=1024

    2.filter_has_var(),针对的是用户原始输出进行判断,看看下面几种情况:
    <?php        $result = filter_has_var(INPUT_GET, 'name');    // 检查GET有没有name变量        var_dump($result);        // 访问下面的url        http://localhost/index.php                      // 输出false        http://localhost/index.php?name=dongxuemin      // 输出true        http://localhost/index.php?name                 // 输出true,值为空,只要定义了,就返回true        // 仍旧是访问http://localhost/index.php,我们手动设置name变量        $_GET['name'] = 'dongxuemin';        http://localhost/index.php                      // 仍旧输出false,可见filter_has_var()针对的是用户原始的输入进行过滤,后续设置并不生效    ?>

    3.filter_input()
    <?php        $result = filter_input(INPUT_GET, 'name');        var_dump($result);        // 访问下面的url        http://localhost/index.php                      // 输出null        http://localhost/index.php?name=dongxuemin      // 输出dongxuemin        http://localhost/index.php?name                 // 输出字符串为""        // 仍旧是访问http://localhost/index.php,我们手动设置name变量        $_GET['name'] = 'dongxuemin';        http://localhost/index.php                      // 仍旧输出null,filter_input()针对的也是用户原始的输入进行过滤,后续设置并不生效        // 当我们设置标志 'FILTER_NULL_ON_FAILURE',那么当变量不存在时返回 FALSE ,当过滤失败时返回 NULL        $result = filter_input(INPUT_GET, 'name', FILTER_DEFAULT, FILTER_NULL_ON_FAILURE);              http://localhost/index.php                      // 输出false    ?>

    4.其它函数都类似这样,看手册例子即可。
    5.如果filter内置的过滤器都满足不了你,怎么办?Filter的内置过滤器中有一个叫FILTER_CALLBACK的,这个过滤器额可以帮组你
    <?php            // 函数方式        function myfilter($str){                return str_replace('9','5',$str);            }            // 类方式        class MyFilter{                public function filter1($str){                    return str_replace('9','6',$str);                }            }            echo filter_var('wo9w9w9',FILTER_CALLBACK,array('options'=>'myfilter'));    // 函数方式的回调        echo filter_var('wo9w9w9',FILTER_CALLBACK,array('options'=>array('MyFilter','filter1')));   // 类方法方式的回调    ?>    

    6.boolean类型的检测可能跟我们的 '自动类型转换' 不同:
        filter_var('abc', FILTER_VALIDATE_BOOLEAN); // bool(false)
        filter_var(11,   FILTER_VALIDATE_BOOLEAN);  // bool(false)
        上面2种情况,返回了false,其实并非是自动转化为boolean类型的false了,而是 “过滤失败”。我们可添加array('flags' => FILTER_NULL_ON_FAILURE)标志-失败时返回null,而非false。
        filter_var('abc', FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE)); // NULL
        filter_var(11,   FILTER_VALIDATE_BOOLEAN, array('flags' => FILTER_NULL_ON_FAILURE));  // NULL
        可被当做boolean的有,下面这些是真正可以过滤成功的:
            字符串:
                'true'
                'TRUE'
                '1'
                'false'
                'FALSE'
                '0'
                ''
            整型:
                1
                0

1 0
原创粉丝点击