复杂数组的PHP输入过滤

时间:2022-04-12 18:31:05

Official PHP documentation states that filter_var_array() supports array filtering in the following format:

官方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);

However, if the array in question is multi-dimensional and requires different filters for different parts, how would you approach defining filtering options?

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

As an example:

举个例子:

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

1 个解决方案

#1


11  

Idea 1

想法1

Consider using FILTER_CALLBACK. In this way, you can write a callback function that itself uses the filter extension, thus providing a recursive ability.

考虑使用FILTER_CALLBACK。通过这种方式,您可以编写一个本身使用过滤器扩展的回调函数,从而提供递归功能。

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

This will generate the callback functions.

这将生成回调函数。

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

This is what the config array would then look like.

这就是配置数组的样子。

Idea 2

想法2

Do not hesitate to pat me on the back for this one because I am quite proud of it.

不要犹豫要拍我的背,因为我为此感到自豪。

Take an arg array that looks like this. Slashes indicate depth.

拿一个看起来像这样的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)
);

Assume your data looks something like this.

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

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

Then, you can generate an array of references that map keys such as 'user/age' to $data['user']['age']. In final production, you get something like this:

然后,您可以生成一个引用数组,将“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));

Now the only question is how you deal with the mismatch between the validation record and the original data set. This I cannot answer without knowing how you need to use them.

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

#1


11  

Idea 1

想法1

Consider using FILTER_CALLBACK. In this way, you can write a callback function that itself uses the filter extension, thus providing a recursive ability.

考虑使用FILTER_CALLBACK。通过这种方式,您可以编写一个本身使用过滤器扩展的回调函数,从而提供递归功能。

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

This will generate the callback functions.

这将生成回调函数。

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

This is what the config array would then look like.

这就是配置数组的样子。

Idea 2

想法2

Do not hesitate to pat me on the back for this one because I am quite proud of it.

不要犹豫要拍我的背,因为我为此感到自豪。

Take an arg array that looks like this. Slashes indicate depth.

拿一个看起来像这样的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)
);

Assume your data looks something like this.

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

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

Then, you can generate an array of references that map keys such as 'user/age' to $data['user']['age']. In final production, you get something like this:

然后,您可以生成一个引用数组,将“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));

Now the only question is how you deal with the mismatch between the validation record and the original data set. This I cannot answer without knowing how you need to use them.

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