【问题标题】:PHP PDO how to search for 2 or more values in a query?PHP PDO 如何在查询中搜索 2 个或多个值?
【发布时间】:2019-08-21 16:34:01
【问题描述】:

假设我有一个搜索表单,我想按姓名或电子邮件进行搜索,但我只能按一个值进行搜索,否则会出现 SQL 错误。

我浏览了该网站,但没有找到解决问题的方法。

此代码有效:

    if (isset($_POST['search'])) {
    $search = $_POST['search'];

    $sql = "SELECT * FROM `users` WHERE `name` LIKE ?";

    $stmt = $pdo->prepare($sql);

    $stmt->execute(array($search));

当我这样尝试时它没有结束:

    if (isset($_POST['search'])) {

    $search = $_POST['search'];

    $sql = "SELECT * FROM `users` WHERE `name` LIKE ? OR `email` LIKE ?";

    $stmt = $pdo->prepare($sql);

    $stmt->execute(array($search));

如何同时通过姓名或电子邮件进行搜索?

编辑: 这是错误:

未捕获的 PDOException: SQLSTATE[HY093]: 参数号无效

EDIT2:

以下是可行的解决方案:

    $search = $_POST['search'];

    if (isset($search)) {

        $sql = "SELECT * FROM `users` WHERE `name` LIKE ? OR `email` LIKE 
    ?";

        $stmt = $pdo->prepare($sql);

        $stmt->execute(["%$search%", "%$search%"]);
    }

【问题讨论】:

  • $search 的 var_dump 是什么?
  • 字符串(9)“某事”

标签: php search pdo


【解决方案1】:

我认为问题在于$search 变量只包含一个元素。试试这个:

$search = $_POST['search'];

if (isset($search)) {

    $sql = "SELECT * FROM `users` WHERE `name` LIKE ? OR `email` LIKE ?";

    $stmt = $pdo->prepare($sql);

    $stmt->execute([$search, $search]);
}

另一种解决方案是将PDO::ATTR_EMULATE_PREPARES 连接选项设置为TRUE。这样,您可以使用多个具有相同名称的命名标记(此处为:search)并为它们分配单个变量的值(此处为组合字符串'%' . $search . '%')。

注意:当使用百分之一或二的字符 (%) 时,查询将返回所有包含提供的搜索值的值。而在完全省略 %-characters 的情况下,查询将返回所有 exact 值,并且 LIKE 可以替换为 =。由您决定使用哪种替代方案。

这是一个完整的例子:

connection.php:

<?php

/*
 * This page contains the code for creating a PDO connection instance.
 */

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'abc');
define('PASSWORD', 'def');
define('CHARSET', 'utf8');

// Error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1); /* SET IT TO 0 ON A LIVE SERVER! */

// Create a PDO instance as db connection to db.
$connection = new PDO(
        sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s', HOST, PORT, DATABASE, CHARSET)
        , USERNAME
        , PASSWORD
        , [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => TRUE, /* This is the option of interest */
    PDO::ATTR_PERSISTENT => FALSE,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
);

test.php:

<?php

require 'connection.php';

// Hardcoded value, for testing. Should be read from $_POST array.
$search = 'joe';

$sql = 'SELECT * FROM users WHERE name LIKE :search OR email LIKE :search';

$bindings = [
    ':search' => '%' . $search . '%',
];

$statement = $connection->prepare($sql);
$statement->execute($bindings);

$fetchedData = $statement->fetchAll(PDO::FETCH_ASSOC);

// Display fetched data.
if ($fetchedData) {
    echo '<pre>' . print_r($fetchedData, TRUE) . '</pre>';
} else {
    echo 'No data found.';
}

结果:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => j.r.
            [email] => joey@example.com
        )

    [1] => Array
        (
            [id] => 3
            [name] => joe
            [email] => joe@example.com
        )

)

表定义:

CREATE TABLE tests.users (
    id BIGINT NOT NULL AUTO_INCREMENT,
    name varchar(100) NULL,
    email varchar(100) NULL,
    CONSTRAINT users_PK PRIMARY KEY (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

使用的数据:

id|name   |email              |
--|-------|-------------------|
 1|j.r.   |joey@example.com   |
 2|michael|michael@example.com|
 3|joe    |joe@example.com    |

资源:

【讨论】:

  • 我认为我不能这样做,因为我的搜索表单中只有一个 $_POST 字段?而且我希望键入的字符串与姓名或电子邮件相匹配,但在一个字段中。
  • 显示你想要执行的真实世界的 sql 查询
  • $search 变量必须是包含两个值的数组,否则您的代码容易发生 sql 注入。
  • 我想执行这个: $sql = "SELECT * FROM users WHERE name LIKE ? OR email LIKE ?";
  • 例如如果你的$search变量是` "joe joe@gmail.com", and you need user with name joe or email joe@gmail.com you can split $search variable to array by space as delimeter explode(' ', $search)` 然后执行查询
猜你喜欢
  • 1970-01-01
  • 2017-11-28
  • 2012-06-24
  • 2014-03-05
  • 2014-11-07
  • 1970-01-01
  • 2017-04-15
  • 2020-05-25
相关资源
最近更新 更多