Php 为foreach()提供的参数无效

Php 为foreach()提供的参数无效,php,foreach,Php,Foreach,我经常处理可以是数组或空变量的数据,并将这些数据提供给一些foreach $values = get_values(); foreach ($values as $value){ ... } 当您向foreach提供非数组的数据时,会收到一条警告: 警告:为[…]中的foreach()提供的参数无效 假设不可能重构get_values()函数以始终返回数组(向后兼容,不可用源代码,无论其他原因),我想知道哪种方法是避免这些警告的最干净、最有效的方法: 将$values强制转换为数组 正

我经常处理可以是数组或空变量的数据,并将这些数据提供给一些
foreach

$values = get_values();

foreach ($values as $value){
  ...
}
当您向foreach提供非数组的数据时,会收到一条警告:

警告:为[…]中的foreach()提供的参数无效

假设不可能重构
get_values()
函数以始终返回数组(向后兼容,不可用源代码,无论其他原因),我想知道哪种方法是避免这些警告的最干净、最有效的方法:

  • $values
    强制转换为数组
  • 正在初始化数组的
    $values
  • if
  • 其他(请建议)

    • 就我个人而言,我觉得这是最干净的-不确定这是否是最有效的,注意

      if (is_array($values) || is_object($values))
      {
          foreach ($values as $value)
          {
              ...
          }
      }
      

      我之所以喜欢它,是因为它不会在没有任何可开始的情况下分配空数组。

      首先,每个变量都必须初始化。总是这样。
      铸造不是一种选择。

      如果获取_值();可以返回不同类型的变量,当然必须检查此值。

      我会做与Andy相同的事情,但我会使用“empty”函数

      像这样:

      if(empty($yourArray))
      {echo"<p>There's nothing in the array.....</p>";}
      else
      {
      foreach ($yourArray as $current_array_item)
        {
          //do something with the current array item here
        } 
      }
      
      if(空($yourArray))
      {echo“数组中没有任何内容….

      ”;} 其他的 { foreach($yourArray作为$current\u array\u项) { //在此处对当前数组项执行某些操作 } }
      我通常使用类似的结构:

      /**
       * Determine if a variable is iterable. i.e. can be used to loop over.
       *
       * @return bool
       */
      function is_iterable($var)
      {
          return $var !== null 
              && (is_array($var) 
                  || $var instanceof Traversable 
                  || $var instanceof Iterator 
                  || $var instanceof IteratorAggregate
                  );
      }
      
      $values = get_values();
      
      if (is_iterable($values))
      {
          foreach ($values as $value)
          {
              // do stuff...
          }
      }
      
      请注意,此特定版本未经测试,它是从内存直接输入SO的

      编辑:添加检查

      尝试以下操作:

      //Force array
      $dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
      foreach ($dataArr as $val) {
        echo $val;
      }
      

      )()

      我不确定情况是否如此,但在迁移wordpress站点或迁移动态站点时,这个问题似乎会出现很多次。如果是这种情况,请确保要迁移到的主机使用与旧站点相同的PHP版本


      如果您没有迁移您的站点,而这只是出现的问题,请尝试更新到PHP5。这就解决了其中的一些问题。可能看起来是一个愚蠢的解决方案,但对我来说却起了作用

      似乎也与环境有关:

      我只在dev环境中出现了“invalid argument supplied foreach()”错误,但在prod中没有(我在服务器上工作,而不是本地主机)

      尽管出现了错误,但var_转储表明该阵列在那里运行良好(在app和dev两种情况下)

      if(is_array($array))
      围绕着
      foreach($array as$subarray)
      解决了这个问题


      很抱歉,我无法解释原因,但由于我花了一段时间才想出一个解决方案,我想最好将此作为一个观察来分享。

      这一个怎么样?整批清洁剂,全部在一条生产线上

      foreach ((array) $items as $item) {
       // ...
       }
      

      警告:为
      foreach()
      display tweets提供的参数无效。 转到
      /wp content/plugins/display tweets php
      。 然后在第591行插入此代码,它将完美运行

      if (is_array($tweets)) {
          foreach ($tweets as $tweet) 
          {
              ...
          }
      }
      

      更简洁的扩展

      特别是用于使用内部模板代码

      <?php foreach (secure_iterable($values) as $value): ?>
          ...
      <?php endforeach; ?>
      
      
      ...
      
      请不要依赖铸造作为解决方案, 尽管其他人认为这是防止错误的有效选项,但它可能会导致另一个错误

      请注意:如果您希望返回特定形式的数组,这可能会使您失败。这需要更多的检查

      例如,将布尔值强制转换为数组
      (array)bool
      ,将不会生成空数组,而是生成一个包含布尔值的元素为int的数组:
      [0=>0]
      [0=>1]

      。 (以下是第一个测试url失败时的示例。)

      包括以下测试:
      null
      false
      true
      数组
      未定义


      在foreach中使用输入之前,请始终测试输入。建议:

    • $array=是数组($var)还是对象($var)$var:[]
    • 在使用foreach和
    • 将foreach包装在if中
    • 使用
      尝试{}catch(){}
    • 在产品发布之前设计适当的代码/测试
    • 要根据正确的形式测试数组,您可以在特定的键上使用
      array\u key\u exists
    • 始终以减少重复代码的方式将助手方法提取到全局命名空间中

    • 这不会检查它是否是数组,但如果变量为null或空数组,则跳过循环。

      如果在foreach循环中将array设置为null,则会出现此通知的例外情况

      if (is_array($values))
      {
          foreach ($values as $value)
          {
              $values = null;//WARNING!!!
          }
      }
      

      问题总是空的,而强制转换实际上是清理解决方案。

      如果您使用php7,并且只想处理未定义的错误,这是最干净的IMHO

      $array = [1,2,3,4];
      foreach ( $array ?? [] as $item ) {
        echo $item;
      }
      

      我将使用
      empty
      isset
      is\u数组的组合作为

      $array = ['dog', 'cat', 'lion'];
      
      if (!empty($array) && isset($array) && is_array($array) {
          //loop
          foreach ($array as $values) {
              echo $values; 
          }
      }
      

      将数组传递给foreach循环时,使用is\u数组函数。

      if (is_array($your_variable)) {
        foreach ($your_variable as $item) {
         //your code
      }
      }
      

      这个解决方案怎么样:

      $type = gettype($your_iteratable);
      $types = array(
          'array',
          'object'
      );
      
      if (in_array($type, $types)) {
          // foreach code comes here
      }
      

      如果
      get\u value()
      为空,那么将空数组定义为回退怎么样?
      我想不出最短的路

      $values = get_values() ?: [];
      
      foreach ($values as $value){
        ...
      }
      

      或者使用count()确定数组是否为空empty@Kemo:
      count()
      不可靠。如果传递
      count()
      null,则返回0。如果向它传递一个非null、非数组参数,它将返回1。因此,当变量可以是空数组或包含1项的数组时,不可能使用
      count()
      确定该变量是否为数组。请注意,某些对象是iterable,而此答案不考虑这些对象。应为
      if(is_array($values)| |$values instanceof Traversable)
      。遗憾的是,他没有继续说这不是最有效的测试,不过:DCasting是一个选项-如果您使用
      $array=(array)null初始化数组得到一个空数组
      
      if (is_array($your_variable)) {
        foreach ($your_variable as $item) {
         //your code
      }
      }
      
      $type = gettype($your_iteratable);
      $types = array(
          'array',
          'object'
      );
      
      if (in_array($type, $types)) {
          // foreach code comes here
      }
      
      $values = get_values() ?: [];
      
      foreach ($values as $value){
        ...
      }