【发布时间】:2013-09-01 22:16:37
【问题描述】:
我正在尝试为我的数据库实现一个非常基本的搜索引擎,其中用户可能包含不同类型的信息。搜索本身由几个联合选择组成,结果总是合并到 3 列中。
然而,返回的数据是从不同的表中获取的。
每个查询都使用 $term 进行匹配,我将它绑定到 ":term" 作为准备参数。
现在,手册说:
当您调用 PDOStatement::execute() 时,您必须为希望传递给语句的每个值包含一个唯一的参数标记。您不能在准备好的语句中使用同名的命名参数标记两次。
我认为与其用 :termX (x for term = n++) 替换每个 :term 参数,还不如有更好的解决方案?
还是我只需要绑定 X 个 :termX?
编辑发布我的解决方案:
$query = "SELECT ... FROM table WHERE name LIKE :term OR number LIKE :term";
$term = "hello world";
$termX = 0;
$query = preg_replace_callback("/\:term/", function ($matches) use (&$termX) { $termX++; return $matches[0] . ($termX - 1); }, $query);
$pdo->prepare($query);
for ($i = 0; $i < $termX; $i++)
$pdo->bindValue(":term$i", "%$term%", PDO::PARAM_STR);
好的,这是一个示例。 sqlfiddle 没时间,以后有需要我会加一个。
(
SELECT
t1.`name` AS resultText
FROM table1 AS t1
WHERE
t1.parent = :userID
AND
(
t1.`name` LIKE :term
OR
t1.`number` LIKE :term
AND
t1.`status` = :flagStatus
)
)
UNION
(
SELECT
t2.`name` AS resultText
FROM table2 AS t2
WHERE
t2.parent = :userParentID
AND
(
t2.`name` LIKE :term
OR
t2.`ticket` LIKE :term
AND
t1.`state` = :flagTicket
)
)
【问题讨论】:
-
首先为什么必须有更好的解决方案? (顺便说一句。您忘记提供具体的 better 在您的情况下意味着什么)和次要的,为什么未命名的参数对您不起作用? (请参阅示例 #2 准备带有问号参数的 SQL 语句 php.net/pdo.prepare)
-
@hakre 未命名参数带来了同样的问题,因为绑定值必须与
?? 一样多。在我的情况下,更好的解决方案是->bindValue(':term', $term)并多次使用 :term 而不是首先构建查询,然后解析它以最终能够准备它。我猜?只会使解析最终查询变得更加困难,因为还有其他参数类型。 -
那么,为什么必须有更好的解决方案?因为你想要?然后,我觉得您的问题与寻找场外资源或图书馆无关。我没有看到底层的编程问题。对不起。
-
@hakre 你是真的还是什么?潜在的编程问题是 API 可能缺少一个关键特性。这就是我想要弄清楚的。我对扩展 PDO 没有任何问题,但我觉得没有必要重新发明轮子。如您所见,我已经解决了它,但觉得必须有更好的方法。
-
如果您有 PDO 的功能请求,请随时为此打开一个问题,但我怀疑这是一个关键功能。关键特性实际上是提供绑定参数,仅此而已。您正在寻找的可能是一个可以更轻松地制定准备好的语句的库,例如 SqlExpression 类或包装/构成/表示准备好的语句的类。而且我看不到您解决了它,代码在哪里?到目前为止,您已经概述了您的要求,但这并不是一个编程问题恕我直言。缺失的特征可能会产生很大的偏差。