【问题标题】:Mysqli parameter binding issueMysqli参数绑定问题
【发布时间】:2010-12-03 00:23:07
【问题描述】:

我需要多加注意这个问题。任何帮助将不胜感激。这是一个非常简单的搜索查询,但无论出于何种原因,我都找不到错误。好吧,我知道错误在哪里。我只是无法克服它。反正.....

我正在从 POST 变量中获取搜索值,设置该变量,然后按如下方式设置列变量...

$term = "'%".$_POST['searchTerm']."%'";
$field = "columnName";

当我回应这些时,它们会完美呈现。因此,如果我在表单中输入“a”,我将回显 '%a%' 和 columnName。

然后我准备查询并绑定参数如下...

$suquery=$dbCon->prepare("select * from Table where ? LIKE ?");
$suquery->bind_param('ss', $field, $term);
$suquery->execute();

结果总是返回 0 行。当我玩这个时,我发现没有一个绑定参数正常工作,即使它应该回显。例如,当我更改查询以使列被硬编码并且只绑定搜索词时......

$suquery=$dbCon->prepare("select * from Table where columnName LIKE ?");
$suquery->bind_param('s', $term);
$suquery->execute();

我仍然得到零返回行。这告诉我,即使 $field 回显为 '%a%' 某些东西仍然关闭。我真的很茫然。同样,当我硬连线搜索词并绑定列时......

$suquery=$dbCon->prepare("select * from Table where ? LIKE '%a%'");
$suquery->bind_param('s', $field);
$suquery->execute();

返回的行太多。它实际上是从表中提取行,其中任何列中的值都包含字母“a”。因此,列或术语都没有正确绑定。五月天!

【问题讨论】:

    标签: php mysql mysqli sql-like parameterbinding


    【解决方案1】:

    编辑:原始答案基于错误假设(假设 PDO 而不是 mysqli)。相应地更改了答案。

    您似乎不允许对列名使用参数替换。来自mysqli::prepare 文档:

    注意:标记仅在 SQL 语句中的某些地方。为了 例如,它们被允许在 INSERT 语句的 VALUES() 列表 (指定行的列值), 或与 a 中的列进行比较 指定比较的 WHERE 子句 价值。但是,它们是不允许的 对于标识符(例如表或 列名),在选择列表中 命名要由 a 返回的列 SELECT 语句,或 ...

    您可能希望通过硬编码查询中的列/字段名称并仅通过参数替换比较值来验证这一点...

    【讨论】:

    • 其实,没有。然而,我确实试图沿着这条路走下去,以努力让它发挥作用。我只是感到困惑。我一直在使用绑定参数,而且我从来没有被困在某件事上这么久。这让我很沮丧。
    • 嗨,我刚刚意识到我的错误 - 应该更仔细地查看标签。我更改了答案,因为问题可能与标识符(表和列名)不允许参数替换有关
    • 汉克,非常感谢您花时间和精力帮助我。关于不允许作为标识符的列名是绝对正确的。这解决了我一半的问题,现在我想知道我是否应该只用另一半重新发布问题。当我硬连接列名时,查询仍然无法正常工作如果我在搜索字段中输入“a”,我会回显“%a%”(单引号是回显的一部分,而不是我在此处添加的内容)作为$字段的值。所以我的查询正在读取“select * from Table where columnName LIKE '%a%'”。结果仍然为零。
    • 我应该补充一点,数据库或查询语法本身没有任何问题,因为我在上面的评论中输入了它。当我将 '%a%' 硬编码到查询中时,它会按预期工作。我认为,我的问题在于单引号,但我不知道如何解决它。如果我在从 _POST 中提取变量时未能将单引号添加到变量中,那么我会收到 mysql 语法错误。没错。
    • 但是您还在 % 前后添加单引号:$term = "'%".$_POST['searchTerm']."%'"; - 应该不需要这些...
    【解决方案2】:
    $suquery=$dbCon->prepare("select * from Table where ? LIKE ?");
    

    不会按预期工作。它将被翻译为:

    SELECT * from table WHERE 'columnName' LIKE '%a%'
    

    它返回所有行,因为“columnName”包含一个“a”。 'columnName' 是一个字符串,而不是实际的列名。

    您的第二次尝试是正确的,只是您在该术语中有一个额外的引号。使用参数时,不需要任何引号。解决办法是:

    $term = "%".$_POST['searchTerm']."%";
    $suquery=$dbCon->prepare("select * from Table where columnName LIKE ?");
    $suquery->bind_param('s', $term);
    $suquery->execute();
    

    【讨论】:

      【解决方案3】:

      只是为了澄清任何偶然发现这一点的人。这个问题相当简单,但奇怪的是,追踪它是一只熊。 Henrik 部分正确。在解析要在我的 LIKE 语句中使用的变量 $term 时,我正在执行以下操作:

      $term = "'%".$_POST['searchterm']."%'";
      

      Henrik 指出我不应该需要用单引号括住我的变量。如果只是将查询准备和执行为:

      $query=$connection->prepare("select * from DATABASE where $field like '$term'");
      $query->execute();
      

      效果很好。但是,我实际上使用 $term 作为绑定参数,这意味着我确实需要单引号,因为语句本身要求搜索词看起来像这样:'%term%'。它需要单引号。如果您尝试将单引号放在绑定参数的问号占位符周围,您将收到语法错误,并且如果您没有将单引号放在您用作绑定参数的变量中,结果将始终为找到 0 行。所以,简而言之,对于遇到这种情况的其他人......如果您直接发送查询,则不需要单引号,因为您可以将它们直接放入 select 语句中。如果您使用绑定参数,则必须将单引号作为变量的一部分,以便查询正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-01
        • 2012-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-28
        • 2010-12-27
        相关资源
        最近更新 更多