2012-08-10 131 views
1

我试图过滤$_POST数据,稍后将其渲染为HTML,即嵌套数组,深入三级。我的结构看起来是这样的:筛选嵌套数组PHP

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和具有硬走在它。我已经成功地过滤了其他数组,但我想知道是否有一种优雅的方式来遍历数组,过滤它们,并返回具有相同结构的对象。

+1

什么会被通缉的结果阵列? – dpitkevics 2012-08-10 13:13:35

+0

基本上是相同的结构:[items] - > array([books] - > array([book1],[book2]),[articles] - > array([article1],[article2]))。 我可以看到做了一系列的foreach循环,但认为可能有一个函数或函数的组合,可以做到这一点。也许filter_input_array,array_walk_recursive,那种事情。 – ghukill 2012-08-10 13:21:55

+0

好的,你想确保没有特殊字符是标题,作者等的一部分吗? – hakre 2012-08-10 13:22:37

回答

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 
       ) 

     ) 

) 
+0

这很完美,谢谢。很高兴能够更熟悉PHP中的stdClass对象。 – ghukill 2012-08-10 15:32:31

+0

谢谢,快乐的编码! – Makita 2012-08-10 15:48:36

0

我可以在这里看到两件事情要验证输入:

  1. 结构 - 如果它没有标题或不是一个作家,例如一本书是不完整的。
  2. 每个字段的数据 - 例如,一本书的标题在它的开始和结束处都没有包含空格。

也许这是一个有点过于简单,但我想突出的是,你需要把你的这些数据类型的认识到您的验证:

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_CALLBACKfilter_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); 

注意,这仅仅是验证。所以它会告诉你总的表单提交是否有效。

0

查看网址: - Filter multidimensional arrays

array_filter接受回调,您可以使用自定义过滤逻辑。这将工作:

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

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

+1

这不起作用,因为您甚至从原始源复制了打字错误。 – gmo 2014-07-28 12:20:25