PHP复杂数组的输入过滤

7
官方的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'))
);
1个回答

11

想法 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

这个想法我非常自豪,别犹豫赞美一下我。

传入一个看起来像这样的参数数组。斜杠表示深度。

$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
这确实是一个好主意,点赞!但我现在唯一的犹豫是它有效地将配置数组的性质从纯声明式部分转变为命令式部分。就我的经验而言,这几乎总是对代码清晰度和可预测行为不利的。 - Dennis Kreminsky
我知道这很混乱。我正在努力找出一些能够产生更清晰配置的方法。 - erisco
啊,终于,在尝试了半打的想法之后,我找到了一个相当美妙的解决方案。 - erisco
哦,这确实很酷,尽管我使用了类似的方法来指定php-xml转换配置,但我没有想到它可以用于过滤目的!你应该得到你的勾号 :) - Dennis Kreminsky
Idea 1在你的validate_array函数中行不通,该函数将使用用户数组的值进行调用。 validate_array将被调用3次,$data将是15,“foo@gmail.com”,38。 - Tony Brix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接