【问题标题】:PHP input filtering for complex arrays复杂数组的 PHP 输入过滤
【发布时间】:2011-06-27 02:26:30
【问题描述】:

PHP 官方文档声明filter_var_array() 支持以下格式的数组过滤:

$data = array(
    'testarray'    => array('2', '23', '10', '12')
);

$args = array(
    'testarray'    => array('filter'    => FILTER_VALIDATE_INT,
                            'flags'     => FILTER_FORCE_ARRAY
                           )    
);

$myinputs = filter_var_array($data, $args);

但是,如果所讨论的数组是多维的并且需要针对不同部分使用不同的过滤器,您将如何定义过滤选项?

举个例子:

$data = array(
    'testhash'    => array('level1'=>'email', 
                           'level2'=> array('23', '10', '12'))
);

【问题讨论】:

    标签: php arrays filter


    【解决方案1】:

    想法 1

    考虑使用 FILTER_CALLBACK。这样,你就可以编写一个回调函数,它本身就使用了过滤器扩展,从而提供了递归的能力。

    function validate_array($args) {
        return function ($data) use ($args) {
            return filter_input_array($data, $args);
        };
    }
    

    这将生成回调函数。

    $args = array(
        'user' => array(
            'filter' => FILTER_CALLBACK,
            'options' => validate_array(array(
                'age' => array('filter' => FILTER_INPUT_INT),
                'email' => array('filter' => FILTER_INPUT_EMAIL)
            ))
        )
    );
    

    这就是配置数组的样子。

    想法 2

    请不要犹豫,为这个拍拍我的后背,因为我为此感到非常自豪。

    取一个像这样的 arg 数组。斜线表示深度。

    $args = array(
        'user/age' => array('filter' => FILTER_INPUT_INT),
        'user/email' => array('filter' => FILTER_INPUT_EMAIL),
        'user/parent/age' => array('filter' => FILTER_INPUT_INT),
        'foo' => array('filter' => FILTER_INPUT_INT)
    );
    

    假设您的数据看起来像这样。

    $data = array(
        'user' => array(
            'age' => 15,
            'email' => 'foo@gmail.com',
            'parent' => array(
                'age' => 38
            )
        ),
        'foo' => 5
    );
    

    然后,您可以生成一个引用数组,将“user/age”等键映射到 $data['user']['age']。在最终的生产中,你会得到这样的东西:

    function my_filter_array($data, $args) {
        $ref_map = array();
        foreach ($args as $key => $a) {
            $parts = explode('/', $key);
            $ref =& $data;
            foreach ($parts as $p) $ref =& $ref[$p];
            $ref_map[$key] =& $ref;
        }
        return filter_var_array($ref_map, $args);
    }
    
    var_dump(my_filter_array($data, $args));
    

    现在唯一的问题是如何处理验证记录与原始数据集之间的不匹配。如果不知道您需要如何使用它们,我无法回答。

    【讨论】:

    • 这确实是个好主意,+1,我现在唯一的犹豫是它有效地将配置数组的性质从纯粹的声明性改变为部分命令性。根据我的经验,这几乎总是对代码清晰度和可预测行为不利。
    • 我知道它很乱。我正在研究一些可以使配置更清晰的方法。
    • 啊,终于,在尝试了六种想法之后,我找到了一个非常漂亮的解决方案。
    • 哦,这确实很酷,尽管我使用了类似的方法来指定php-xml转换配置,但我没想到它是为了过滤目的!你值得你的复选标记:)
    • 想法 1 在您的 validate_array 函数中不起作用,将使用用户数组的值调用。 validate_array 将被调用 3 次, $data 将是 15, "foo@gmail.com", 38
    猜你喜欢
    • 2011-02-15
    • 2012-03-18
    • 2018-10-20
    • 2019-08-16
    • 2018-02-01
    • 1970-01-01
    • 2016-10-22
    • 2021-11-05
    • 1970-01-01
    相关资源
    最近更新 更多