从PHP中的嵌套数组中获取所有值?

从PHP中的嵌套数组中获取所有值?,php,Php,对于此嵌套数组: $status = array( "house" => "OK", "car" => array( "car1" => "OK", "car2" => "ERROR" ), "boat" => "OK" ); 我想知道数组中是否至少存在一次特定值错误。我不在乎它与什么键关联,我只想知道$status数组中是否有错误状态 除了使用嵌套for循环迭代元素外,还有更干净的方法吗?您可以使用函数array\u

对于此嵌套数组:

$status = array(
  "house" => "OK",
  "car" => array(
      "car1" => "OK",
      "car2" => "ERROR"
   ),
   "boat" => "OK"
);
我想知道数组中是否至少存在一次特定值错误。我不在乎它与什么键关联,我只想知道$status数组中是否有错误状态


除了使用嵌套for循环迭代元素外,还有更干净的方法吗?

您可以使用函数array\u walk\u recursive来获取具有任何嵌套数组级别的所有值


您可以使用函数array\u walk\u recursive获取所有嵌套数组级别的值


实际上,我不会使用数组递归。它在你想做的几件关键事情上都有不足之处。虽然一开始它看起来像是通往你想要的东西的捷径,但如果在几个关键方面失败了:

不能从回调中返回简单的可测试值,比如布尔值true或false。 不能使用嵌套构建$all数组,因为将数组作为其值的键永远不会传递给回调。这实际上是将阵列展平。 它不可移植,或者换句话说,它不可重用,因为它本质上是程序性的。 也就是说,老实说,我不会构建all数组,因为它毫无意义,因为您已经拥有了该数组,所以复制它没有意义。正如我所说,我不认为你真的想重建$all,但如果你真的想重建$all,你就不能用array\u walk\u recursive来重建它,即使你想

无论如何

true
true
false
印刷品

$status = array(
  "house" => "OK",
  "car" => array(
      "car1" => "OK",
      "car2" => "OK"
   ),
   "boat" => "OK"
);
测试一下

更新 我看到你改变了问题,当你说值时,你的数组说的是键

function checkRecursive($value, $array){  
    $x = false;
    foreach($array as $k=>$v){
        if(is_array($v)) $x = checkRecursive($value, $v); //recursive
        if((string)$value == (string)$k || $x == true) return true;
    }
    return false;
}
因为所有的值都是相同的。所以,如果你真的想找到钥匙,那就把它改成这个

echo '(int)"one": ';
echo (int)"one";
echo "\n";
echo "0 == 'one': " . (0 == "one" ? "true\n" : "false\n");
echo "1 == '1': " . (1 == "1" ? "true\n" : "false\n");
在检查键时需要注意的几点是,它们可能并不总是字符串,或者您将使用未量化的数字进行检查。在这些情况下,PHP有时会使用一种奇怪的方式将字符串更改为整数,而非数字字符串将显示为0。例如,1=1,但当作为整数时,1=0。因此,如果您有一个键为0的数组,并且您检查其中一个,它将与之匹配,因为它将把一个变为0

您可以通过将所有内容转换为字符串来解决此问题。或者使用===严格类型检查。我更喜欢string方法,因为使用===进行检查将得到0!=因此,如果您尝试用0查找0的键,它会说不匹配。其他数字也是如此。除非您计划用它检查对象

在查找值时,这仍然是一个问题,但它不是一个问题,因为您没有处理数组中的本机整数键,因此更可能不会遇到它

这一切都与PHP的松散类型性质有关,这是一个特性,而不是一个bug

我把这个小例子放在一起:

(int)"one": 0
0 == 'one': true
1 == '1': true
产出:

干杯


:-p

我实际上不会使用数组递归。它在你想做的几件关键事情上都有不足之处。虽然一开始它看起来像是通往你想要的东西的捷径,但如果在几个关键方面失败了:

不能从回调中返回简单的可测试值,比如布尔值true或false。 不能使用嵌套构建$all数组,因为将数组作为其值的键永远不会传递给回调。这实际上是将阵列展平。 它不可移植,或者换句话说,它不可重用,因为它本质上是程序性的。 也就是说,老实说,我不会构建all数组,因为它毫无意义,因为您已经拥有了该数组,所以复制它没有意义。正如我所说,我不认为你真的想重建$all,但如果你真的想重建$all,你就不能用array\u walk\u recursive来重建它,即使你想

无论如何

true
true
false
印刷品

$status = array(
  "house" => "OK",
  "car" => array(
      "car1" => "OK",
      "car2" => "OK"
   ),
   "boat" => "OK"
);
测试一下

更新 我看到你改变了问题,当你说值时,你的数组说的是键

function checkRecursive($value, $array){  
    $x = false;
    foreach($array as $k=>$v){
        if(is_array($v)) $x = checkRecursive($value, $v); //recursive
        if((string)$value == (string)$k || $x == true) return true;
    }
    return false;
}
因为所有的值都是相同的。所以,如果你真的想找到钥匙,那就把它改成这个

echo '(int)"one": ';
echo (int)"one";
echo "\n";
echo "0 == 'one': " . (0 == "one" ? "true\n" : "false\n");
echo "1 == '1': " . (1 == "1" ? "true\n" : "false\n");
在检查键时需要注意的几点是,它们可能并不总是字符串,或者您将使用未量化的数字进行检查。在这些情况下,PHP有时会使用一种奇怪的方式将字符串更改为整数,而非数字字符串将显示为0。例如,1=1,但当作为整数时,1=0。因此,如果您有一个键为0的数组,并且您检查其中一个,它将与之匹配,因为它将把一个变为0

您可以通过将所有内容转换为字符串来解决此问题。或者使用===严格类型检查。我更喜欢string方法,因为使用===进行检查将得到0!=因此,如果您尝试用0查找0的键,它会说不匹配。其他数字也是如此。除非您计划用它检查对象

在查找值时,这仍然是一个问题,但它不是一个问题,因为您没有处理数组中的本机整数键,因此更可能不会遇到它

这一切都与PHP的t有关 键入的性质,这是一个功能,而不是一个错误

我把这个小例子放在一起:

(int)"one": 0
0 == 'one': true
1 == '1': true
产出:

干杯


:-p

您知道是否可以有多个嵌套吗?或者只是两层?这样做你怎么知道哪个OK适用于哪个信息????您需要的是您仍然需要向它传递一个回调,将$value放入$all。您知道是否可以有多个嵌套吗?或者只是两层?这样做你怎么知道哪个OK适用于哪个信息????您需要的是,您仍然需要向它传递一个回调,将$value放入$all中。$all将是一个空数组,除非您将它放入闭包函数$value、$key use&$all的use部分,并从主参数中删除它,只需说一句。因为array\u walk\u recursive不通过引用传递额外的参数,因此不能更新为其超出范围。即使如此,您仍然在减少$all数组,因为您没有记录键。。。就个人而言,我说您可能可以将其全部删除,但我不知道这如何返回可测试值。在任何情况下,都会丢失$all中的嵌套键,因为array\u walk\u recursive不会将它们作为值传递给带有array的回调。它只传递带有非数组值的键,换句话说,它会将数组展平。$all将是一个空数组,除非您将它放在闭包函数$value、$key use&$all的use部分,并从主参数中删除它,只需说。因为array\u walk\u recursive不通过引用传递额外的参数,因此不能更新为其超出范围。即使如此,您仍然在减少$all数组,因为您没有记录键。。。就个人而言,我说您可能可以将其全部删除,但我不知道这如何返回可测试值。在任何情况下,都会丢失$all中的嵌套键,因为array\u walk\u recursive不会将它们作为值传递给带有array的回调。它只传递带有非数组值的键,换句话说,它会使数组变平。