PHP PDO, как искать 2 или более значений в запросе? - PullRequest
0 голосов
/ 31 марта 2019

Допустим, у меня есть форма поиска, и я хочу выполнить поиск по имени или электронной почте, мне удается выполнить поиск только по одному значению, в противном случае я получаю ошибку 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));

Как мне найти его по имени или по электронной почте?

EDIT: Вот ошибка:

Uncaught 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%"]);
    }

1 Ответ

1 голос
/ 31 марта 2019

Я считаю, что проблема в том, что переменная $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 . '%').

Примечание: при использовании одного или двух процентов символов (%) запрос вернет все значения , содержащие предоставленное значение поиска. Принимая во внимание, что в случае полностью пропущенных % -характеров запрос вернет все точные значения, и 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:

<code><?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) . '
'; } еще { echo 'Данные не найдены.'; }

Результаты:

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    |

Ресурсы:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...