过滤嵌套数组PHP

时间:2012-08-10 13:12:16

标签: php arrays parsing filtering

我正在尝试过滤$_POST数据,然后将其渲染为HTML,即嵌套数组,大约有三个级别。我的结构看起来像这样:

Array
(
    [books] ==> Array
    (
        [book1] ==> Array
        (
            [0] ==> Title
            [1] ==> Author                    
        )
        [book2] ==> Array
        (
            [0] ==> Title
            [1] ==> Author
        )
    )

    [articles] ==> Array
    (
        [article1] ==> Array
        (
            [0] ==> Journal
            [1] ==> Title                    
        )
        [article2] ==> Array
        (
            [0] ==> Journal
            [1] ==> Title
        )
    )
)

我有这种直觉,有一种方法可以使用foreach循环和filter_input_arrays(使用数组和清理参数),但我对PHP很陌生并且很难实现它。我已经成功地过滤了其他数组,但我想知道是否有一种优雅的方式来迭代数组,过滤它们,并返回一个具有相同结构的对象。

3 个答案:

答案 0 :(得分:1)

请参阅网址: - Filter multidimensional arrays

array_filter接受可用于自定义过滤逻辑的回调。这可行:

$filtered = array_filter($array, function($el) { return !empty($el['mob']; });

这里回调是作为匿名函数提供的。

答案 1 :(得分:1)

这将递归过滤数据并按要求返回对象,在清理函数中选择过滤器方法。您可以使用此功能深入多个级别,并且具有不对称结构。

$arrayData = array (
    'books' => array ( array ( 'Title1','Author1' ), array ( 'Title2','Author2' )),
    'articles' => array ( array ( 'Journal3','Title3' ), array ( 'Journal3','Title3' ))

);

function arrayFilter($arrayIn){
    $output = null;
    if (is_array($arrayIn)){
        foreach ($arrayIn as $key=>$val){
            if (is_array($val)){
                $output->{$key} = arrayFilter($val);
            } else {
                $output->{$key} = sanitize($val);
            }
        }
    } else {
        $output->{$key} = sanitize($val);
    }
    return $output;
}

function sanitize($val)
{
    //insert your preferred data filter here
    return addslashes('filtered: '.$val);
}

print_r (arrayFilter($arrayData));

输出:

stdClass Object
(
    [books] => stdClass Object
        (
            [0] => stdClass Object
                (
                    [0] => filtered: Title1
                    [1] => filtered: Author1
                )

            [1] => stdClass Object
                (
                    [0] => filtered: Title2
                    [1] => filtered: Author2
                )

        )

    [articles] => stdClass Object
        (
            [0] => stdClass Object
                (
                    [0] => filtered: Journal3
                    [1] => filtered: Title3
                )

            [1] => stdClass Object
                (
                    [0] => filtered: Journal3
                    [1] => filtered: Title3
                )

        )

)

答案 2 :(得分:0)

我可以在这里看到两件要验证输入的内容:

  1. 结构 - 如果书籍没有标题或者不是作者,则书籍不完整。
  2. 每个字段数据 - 例如,一本书的标题在开头和结尾都不包含空格。
  3. 也许这有点过于简化,但我想强调的是,您需要将对这些数据类型的理解纳入验证:

    function books_is_valid(array $books) {
         foreach ($books as $book) {
             if (!$book_is_valid($bool) {
                 return false;
             }
         }
         return true;
    }
    
    function book_is_valid(array $book) {
        if (!count($book) === 2) return false;
        if (!array_keys($book) === array(0, 1)) return false;
        if (!book_title_is_valid($book[0])) return false;
        if (!book_author_is_valid($book[1])) return false;
        return true;
    }
    
    book_title_is_valid($title) {
         ... # do your checks, return bool
    }
    
    book_author_is_valid($author) {
         ... # do your checks, return bool
    }
    

    就像您的数据结构很复杂一样,您的验证也是如此。由于您甚至有不同的复杂数据类型,如书籍和文章,您可以自己编写一些通用函数来支持这些类型的输入,这样您就可以将重复的代码移动到它自己的函数中,并在以后删除复制。

    然后,您可以使用FILTER_CALLBACK来使用具有filter_input_array功能的特定过滤器:

    $args = array(
        'books'    => array('filter'  => FILTER_CALLBACK,
                            'options' => 'books_is_valid', 
                           ),
        'articles' => array('filter'  => FILTER_CALLBACK,
                            'options' => 'articles_is_valid', 
                           ),
    );
    
    $myinputs = filter_input_array(INPUT_POST, $args);
    
    var_dump($myinputs);
    

    请注意,这只是验证。因此,它会告诉您总共提交的表单是否有效。