【问题标题】:php: unable to iterate for each loopphp:无法为每个循环迭代
【发布时间】:2013-09-25 17:04:50
【问题描述】:

我正面临以下代码的以下错误:

错误:

Warning: Invalid argument supplied for foreach() 

代码:

 //--------This is the code for jquery UI autocompleter-------------

include "inc/connect.php";
$skeyword = $_GET["term"];
$req = "SELECT  p.prm_title ,a.am_name, c.cm_name ,l.lm_name ,b.bm_name,r.pm_name  "
    . "FROM product_master p,author_master a,category_master c,language_master l,binding_master b ,publisher_master r "
    . "WHERE p.prm_title LIKE '%$skeyword%' OR a.am_name LIKE '%$skeyword%'
       OR c.cm_name LIKE '%$skeyword%' OR l.lm_name LIKE '%$skeyword%' OR b.bm_name LIKE '%$skeyword%' OR r.pm_name LIKE '%$skeyword%'  
       GROUP BY p.prm_id LIMIT 10";

$res = mysql_query($req);
$ret = array();
foreach (mysql_fetch_array($res) as $row) {
    foreach ($row as $val) //--Error: from this line, Why?
    {
        if (false !== stripos($val, $skeyword)) {
            $ret[] = $val;
            break;
        }
    }
}

$testme = json_encode($ret);
echo $testme;

上面的代码是为jquery自动完成器在多列字段中搜索而编写的,但它只会返回匹配的列。

请帮我解决这个问题..

【问题讨论】:

  • 将您的第一个 foreach 更改为 while 循环。见mysql_fetch_arraymanual

标签: php jquery autocomplete


【解决方案1】:

为什么:

如果是变量:

  • 不是array
  • 没有实现接口Iterator

并且它被foreach 用于迭代器,这个错误将会引发。


如何解决

mysql_fetch_array 返回对应于获取行的字符串数组,如果没有更多行,则返回FALSE,因此使用while 循环获取结果:

while ($row = mysql_fetch_array($res))
{
    // if $row is false, the code will not hit here.
    foreach ($row as $val)
    {
        if (FALSE !== stripos($val, $skeyword))
        {
            $ret[] = $val;
            break;
        }
    }
} 


更新:

    while ($row = mysql_fetch_array($res))
    {
        // if $row is false, the code will not hit here.
        foreach ($row as $val)
        {
            if (FALSE !== stripos($val, $skeyword) && !in_array($val, $ret))
            {
                $ret[] = $val;
                break;  // what this break for?
            }
        }
    } 

【讨论】:

  • 据我所知,不会。您会将输出粘贴到您的问题中吗?
  • 是的,它重复了,我搜索了一个关键字ravi 作为作者名,然后我得到了像["Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere","Ravi Belagere"] 这样的输出它返回了这个作者所属的所有书表行
  • 好的,如果你只想获取one record,试试我更新中的代码。
  • 对不起,你不明白我的确切问题。上面显示的新更新 u 不适用于多数据匹配。我只想要 SAME 匹配关键字的 1 个结果。例如:值 hellohello 相同,所以它们应该只出现一次,但如果我有像 hellohello9 这样的值,那么两者都应该出现。
【解决方案2】:

请试试这个。 使用while 而不是foreach

//--------This is the code for jquery UI autocompleter-------------

include "inc/connect.php";
$skeyword = $_GET["term"]; 
$req = "SELECT  p.prm_title ,a.am_name, c.cm_name ,l.lm_name ,b.bm_name,r.pm_name  "
        . "FROM product_master p,author_master a,category_master c,language_master l,binding_master b ,publisher_master r "
        . "WHERE p.prm_title LIKE '%$skeyword%' OR a.am_name LIKE '%$skeyword%'
                      OR c.cm_name LIKE '%$skeyword%' OR l.lm_name LIKE '%$skeyword%' OR b.bm_name LIKE '%$skeyword%' OR r.pm_name LIKE '%$skeyword%'  
                      GROUP BY p.prm_id LIMIT 10";

    $res = mysql_query($req);
            $ret = array();
            while ($row = mysql_fetch_array($res))
            {
                foreach ($row as $val)   //--Error: from this line, Why?
                {
                    if (FALSE !== stripos($val, $skeyword))
                    {
                        $ret[] = $val;
                        break;
                    }
                }
            } 

$testme = json_encode($ret);
echo $testme;

【讨论】:

  • 为什么我不能使用每个循环...为什么当我保留 while 时它会起作用?
【解决方案3】:
while ($row = mysql_fetch_array($res)) {

【讨论】:

    【解决方案4】:

    再次,但现在作为答案:

    将您的第一个 foreach 更改为 while 循环。见mysql_fetch_arraymanual

    【讨论】:

      【解决方案5】:

      始终验证“foreach”的参数是否为数组。 如果没有符合您的条件的行,您的 SQL 请求可能会返回 FALSE,并且 FALSE 上的 foreach 不起作用:)

      所以在你的代码之后

      foreach (mysql_fetch_array($res) as $row)
      

      在尝试迭代之前,您必须验证 $row 是一个数组而不是 false。

      if (is_array($row))
      

      或者你可以更明确地使用mysql_num_rows,它会告诉你查询是否返回一些行:

      if (mysql_num_rows($res) > 0) 
      {
          $ret = array();
          foreach ( mysql_fetch_array($res) as $row)
          // ...
      }
      

      但是,正如上面 djot 和 Amol 所揭示的那样,正确的解决方案是使用

      while ($row = mysql_fetch_array($res))
      

      这确保如果 $row 为 FALSE,那么您将不会进入该块并且您不会尝试在 FALSE 上进行迭代。

      【讨论】:

        最近更新 更多