【问题标题】:Can you pass multiple params using OR to an SQL/PHP single bind statement?您可以使用 OR 将多个参数传递给 SQL/PHP 单个绑定语句吗?
【发布时间】:2018-03-22 16:51:58
【问题描述】:

我有一个将数据传递到服务器的搜索栏。我将发送的句子分解成单个单词。

然后我将一列与句子中的每个单词进行比较。

$term = filter_var($input['term'], FILTER_SANITIZE_STRING);
$terms = explode(" ", $term);
$size = sizeof($terms);

$posts = DB::select('SELECT * FROM cars
WHERE color = ?',
$terms[0] || $terms[1] || $terms[2] || $terms[3] || $terms[4] );

在一个绑定上绑定多个参数的正确方法是什么?

这种方式会变得很乱,因为我想搜索其他列。

for ($i=0; $i < $size ; $i++) {
    $posts = DB::select('SELECT * FROM cars
        WHERE color = ? AND
        WHERE model =?',
    $terms[$i], $terms[$i],);
}

【问题讨论】:

  • 是的,但您只需要一个WHERE,即WHERE color = ? AND model =?
  • 或者对多个键使用WHERE color IN (?)
  • SQL 手册或一些教程的偷偷摸摸的高峰似乎是您在接下来的几个小时内应该做的事情

标签: php mysql sql bindparam


【解决方案1】:

在一个绑定中绑定多个参数的正确方法是什么。

想想这条规则:您可以在 SQL 查询中使用参数来代替单个标量值

也就是说,您通常在 SQL 语句中使用一个数字常量、一个带引号的字符串常量或一个带引号的日期常量,您可以用一个参数替换那个查询元素。

参数不能用来代替:

  • 多个值的列表
  • SQL 表达式
  • SQL 关键字
  • 标识符,如表名、列名或数据库名

如果要将color 列与多个值进行比较,则需要多个参数占位符。

$posts = DB::select('SELECT * FROM cars
WHERE color IN (?, ?, ?, ?)');

将包含逗号分隔值列表的字符串传递给单个占位符是行不通的。您最终会得到一个查询,就好像您是这样编写的:

SELECT * FROM cars WHERE color IN ('12,34,56,78');

此查询将毫无错误地运行,但它不会给你想要的。在数字上下文中,字符串'12,34,56,78' 的数值为12。它忽略字符串中第一个非数字字符, 之后的所有其余字符。所以它会成功搜索到 12 号颜色,但是它会找不到其他颜色。


PDO 使处理值列表变得容易,因为当需要为参数化查询提供值时,您可以简单地将数组传递给PDOStatement::execute() 函数。

如果您不知道需要搜索多少个颜色值,您可以使用 PHP 内置函数创建一个与颜色值数组长度相同的问号占位符列表:

$list_of_question_marks = implode(',', array_fill(1, count($color_values), '?'));
$sql = "SELECT * FROM cars WHERE color IN ($list_of_question_marks)" 
$stmt = $pdo->prepare($sql);
$stmt->execute($color_values);

【讨论】:

  • @seamus 对于严格使用mysqli(不是pdo)动态构建和绑定,您将使用call_user_func_array。 PDO 确实使execute 变得更容易......但如果您仍然希望坚持使用 mysqli(服务器原因或其他原因),则不需要它。
  • @IncredibleHat 曾经有一段时间人们使用 mysqli,因为默认情况下 PDO 还不是 PHP 发行版的一部分。 那是 2005 年。 是时候将 PDO 视为 PHP 环境的正常部分了。
  • 好吧,考虑到它的 2018 年......而且我仍然在禁用 PDO 的新服务器上运行......我认为有必要提到在 mysqli 中仍有一些方法可以做事;)它不是根本不会对你的回答大发雷霆。
  • 确实,根据您的 Linux 发行版,PDO 是一个单独的 yum/apt 包。但是mysqli也是如此。以及许多其他常见的 PHP 扩展。
【解决方案2】:

你应该使用 In 在各个项目之间进行搜索,如果是搜索,使用 OR 运算符会更好:

    $posts = DB::select('SELECT * FROM cars
    WHERE color in (?) or
    model in (?)',
    implode(',', $terms), implode(',', $terms));

【讨论】:

  • 我不确定这将如何工作(请参阅比尔的回答)。例如传递 "look" "for" "this" 的 $terms 将变成 "look,for,this" 的字符串(内爆)。然后将其作为单个字符串准备并绑定到单个?。它不会是IN 需要的逗号分隔列表:IN ('look','for','this')。它将改为IN ('look,for,this')。没有。
  • 没错,这个问题有一个更好(和正确)的答案。
  • 是的..我会删除它,但我不能,因为它是选择的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 2013-03-22
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
相关资源
最近更新 更多