0

我需要一些关于我的代码的帮助。到目前为止,当我转到页面时,可以看到整个视图。当我设置搜索并发布它时,它也可以工作。但是当我添加 --> 2 个或更多 <-- 关键字时,我得到一个错误。所以问题出在 forarch 循环 else 构造中。

在这种情况下,我收到此错误:

查询 fout 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 6 行的“ORDER BY custsurname、custforename、custmidname”附近使用正确的语法

我尝试了许多构建方法,但不知何故似乎不起作用。

我的代码如下:

if(isset($_POST['search']))
{
    $search = $_POST['search'];
    $terms = explode(" ", $search);
    $customerlistquery = "
    SELECT * 
    FROM customer
    LEFT JOIN company
    ON customer.compid=company.compid
    WHERE 
    ";

    foreach ($terms as $each) 
    {
        $i++;

        if ($i == 1)
        {
            $customerlistquery .= "concat(custsurname, custforename, custmidname) LIKE '%$each%' ORDER BY custsurname, custforename, custmidname";
        }
        else
        {
            $customerlistquery .= "OR concat(custsurname, custforename, custmidname) LIKE '%$each%' ORDER BY custsurname, custforename, custmidname";
        }
    }
}
else
{
$customerlistquery = "  
        SELECT *
        FROM customer
        LEFT JOIN company
        ON customer.compid=company.compid
        ORDER BY custsurname, custforename, custmidname
        ";
}

还有最后一个问题。为什么 PHP 抱怨 undefined 变量:i

Notice: Undefined variable: i in ...

这是每个“一次性变量”的标准消息吗?

4

2 回答 2

2

@newfurniturey 是对的,您第一次使用$i, 在这里:$i++;基本上,您添加1到不存在的东西:$i尚未声明,因此您没有可以添加 1 的值。

是的,你可以把通知关掉,把它们藏起来。但是,您的日志会很快变得混乱。因此,最好以这样的方式编写代码,使其在E_STRICT | E_ALL设置下运行而不会出现任何警告或通知。

在你解决了这个问题之后,我现在可以告诉你,你也会到处看到 SQL 语法错误:

foreach ($terms as $i => $each) 
{//use the index in a foreach loop, that's the easiest solution
    if ($i === 0)
    {
        $customerlistquery .= "concat(custsurname, custforename, custmidname) LIKE '%$each%' ORDER BY custsurname, custforename, custmidname";
    }
    else
    {
        $customerlistquery .= "OR concat(custsurname, custforename, custmidname) LIKE '%$each%' ORDER BY custsurname, custforename, custmidname";
    }
}

您连接的每一位查询都以 ORDER BY 子句结尾。SQL 不会接受看起来像的查询

SELECT foo FROM db.bar WHERE x LIKE '%Y%' ORDER BY x,z OR x LIKE '%x%' ORDER BY x,z

所以我建议你在循环之后ORDER BY连接子句:

foreach ($terms as $i => $each) 
{//use the index in a foreach loop, that's the easiest solution
    if ($i === 0)
    {
        $customerlistquery .= "concat(custsurname, custforename, custmidname) LIKE '%$each%'";
    }
    else
    {
        $customerlistquery .= "OR concat(custsurname, custforename, custmidname) LIKE '%$each%'";
    }
}
$customerlistquery .= ' ORDER BY custsurname, custforename, custmidname';

一旦你让这个查询运行,如果它的速度很慢,不要感到惊讶:最慢的查询的前 3 件事是:

  1. 索引错误
  2. 过度LIKE使用通配符
  3. 很多OR条款

如果您的查询具有这三个特征中的两个,那么 SQL 将有 99% 的机会执行全表扫描并将临时表写入磁盘。那么远非理想。

于 2012-10-17T15:26:52.680 回答
1

关于您的 SQL 错误 - 您正在遍历术语列表以构建WHERE子句。但是,在每次迭代中,您附加的查询也包含一个ORDER BY子句。使用一个术语,这将正常工作。2+ 个术语,并且您的 SQL 无效。

尝试更新循环以仅附加WHERE-clause 项并添加以下内容ORDER BY

foreach ($terms as $each) {
    if ($i++ > 0) $customerlistquery .= ' OR ';
    $customerlistquery .= "concat(custsurname, custforename, custmidname) LIKE '%$each%' ";
}
$customerlistquery .= " ORDER BY custsurname, custforename, custmidname";

我还稍微更改了您的循环以完成相同的任务,但没有重复的代码。

为了解决有关您的undefined variable警告的问题,当您尝试使用变量而不声明它时会发生这种情况。在 if 的情况下$i,您从未定义它(例如$i = 0;),但您使用$i++- 这会导致警告。

您可以使用以下方法关闭这些通知:

error_reporting(E_ALL ^ E_NOTICE);

但是,您实际上在代码中使用了变量;相反,$i = 0;在进入循环之前添加foreach以解决实际问题。

于 2012-10-17T15:12:39.457 回答