Mysqli参数绑定问题

时间:2009-10-01 14:09:09

标签: php mysql mysqli sql-like parameterbinding

我需要额外的一双眼睛。任何帮助将不胜感激。这是一个非常简单的搜索查询,但无论出于何种原因,我找不到该错误。好吧,我知道bug在哪里。我只是无法超越它。无论如何.....

我从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”。因此,列或术语都没有正确绑定。五月天!

3 个答案:

答案 0 :(得分:6)

$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();

答案 1 :(得分:2)

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

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

  

注意:标记仅在合法中使用   SQL语句中的某些位置。对于   例如,他们被允许进入   VALUES()INSERT语句的列表   (指定行的列值),   或者与a中的列进行比较   WHERE子句指定比较   值。但是,他们是不允许的   用于标识符(例如表或   列名称),在选择列表中   命名要由a返回的列   SELECT语句,或......

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

答案 2 :(得分:0)

只是要澄清任何绊倒这个的人。这个问题相当简单,但跟踪它是一只熊是很奇怪的。亨里克部分正确。解析变量$ term以在我的LIKE语句中使用时,我正在执行以下操作:

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

Henrik指出我不应该将单引号括在我的变量中。如果只是准备和执行查询,则确实如此:

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

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