Всех приветствую, товарищи! Хочу сделать поиск человека из БД по его данным, но почему-то данный запрос возвращает последнего из списка, независимо от введённых данных. А хотел бы, чтобы возвращал список из тех, данные которых совпали с запросом поиска. Не могли бы подсказать, в чём моя ошибка? PHP: $stmtKlientS = $mb->prepare("SELECT id, name, tel, email, FROM clients WHERE id = :id OR name LIKE :name OR tel LIKE :tel OR email LIKE :email ORDER BY name "); $stmtKlientS->bindValue(':id', (int)$_POST['klId']); $stmtKlientS->bindValue(':name', "%".trim($_POST['name'])."%"); $stmtKlientS->bindValue(':tel', "%".(int)$_POST['tel']."%"); $stmtKlientS->bindValue(':email', "%".trim($_POST['email'])."%"); $stmtKlientS->execute(); $dataKlientS = $stmtKlientS->fetchAll(PDO::FETCH_ASSOC); foreach($dataKlientS as $itemKlientS){ $klientS = "<tr data-id='".$itemKlientS['id']."'><td>".$itemKlientS['id']."</td><td>".$itemKlientS['name']."</td><td>+7".$itemKlientS['tel']."</td><td>".$itemKlientS['email']."</td></tr>"; } echo $klientS;
$klientS .= PHP: <?php $stmtKlientS = $mb->prepare("SELECT id, name, tel, email, FROM clients WHERE id = :id OR name LIKE :name OR tel LIKE :tel OR email LIKE :email ORDER BY name "); $stmtKlientS->bindValue(':id', (int)$_POST['klId']); $stmtKlientS->bindValue(':name', "%".trim($_POST['name'])."%"); $stmtKlientS->bindValue(':tel', "%".(int)$_POST['tel']."%"); $stmtKlientS->bindValue(':email', "%".trim($_POST['email'])."%"); $stmtKlientS->execute(); $dataKlientS = $stmtKlientS->fetchAll(PDO::FETCH_ASSOC); $klientS = ''; foreach($dataKlientS as $itemKlientS){ $klientS .= "<tr data-id='".$itemKlientS['id']."'><td>".$itemKlientS['id']."</td><td>".$itemKlientS['name']."</td><td>+7".$itemKlientS['tel']."</td><td>".$itemKlientS['email']."</td></tr>"; } echo $klientS;
@Булат, общие замечания: 1) делать SELECT-ы без LIMIT-ов, а потом ещё и fetchAll() крайне вредно, вдруг результатом выборки будет лям записей, скрипт треснет по выделяемой оперативной памяти; 2) даже без использования шаблонизаторов (php сам себе шаблонизатор) логику рекомендуется отделять от представления.
Последнюю запись он возвращает потому что у тебя echo один раз выполняется. Если хочешь выводить каждую запись результата, помести echo внутрь цикла. --- Добавлено --- Ну или как @Aleksandr.B указал: .= будет подклеивать новые строки к результату, накапливать его перед выводом. --- Добавлено --- Но помоему проще было бы использовать мощь PHP как языка для веб: при выводе тебе можно обойтись без промежуточной переменной. PHP: $klientS = "<tr data-id='".$itemKlientS['id']."'><td>".$itemKlientS['id']."</td><td>".$itemKlientS['name']."</td><td>+7".$itemKlientS['tel']."</td><td>".$itemKlientS['email']."</td></tr>"; echo $klientS; работает так же как PHP: ?> <tr data-id="<?= $itemKlientS['id'] ?>"> <td><?= $itemKlientS['id'] ?></td> <td><?= $itemKlientS['name'] ?></td> <td>+7<?= $itemKlientS['tel'] ?></td> <td><?= $itemKlientS['email'] ?></td> </tr> <?php --- Добавлено --- Так ведь нагляднее, правда? Легче править когда понадобится.
@Aleksandr.B, спасибо! Забыл точку поставить. @don.bidon, спасибо! Как-то не додумался ставить LIMIT-ы. Теперь поставил везде, где может выдать очень много результатов. @don.bidon, имеете ввиду, что нужно использовать апострофы? @artoodetoo, знаю, что так делают. Но я не совсем понимаю, как это делается. У меня есть очень длинные подобные строки с HTML-кодом с присваиванием к переменным. Действительно, очень неудобно править, поэтому я обычно правку делаю в отдельном HTML-файле, а потом копирую нужное в PHP, в строку. Например, при входе в админ-зону создаётся сессия, после проверка - если существует сессия, к какой-то переменной присваиваем текст с TML-кодом (который должен отображаться только тем, кто зашёл в админку). Можно ли данный код переделать в такой, который вы показали выше? PHP: <?php session_start(); require_once("adminRt.php"); require(__DIR__ . '/admin/' . $rtAdm[$routePath]); $style = "<link href='/css/styleAdmin.css' type='text/css' rel='stylesheet'>"; $JS = "<script src='/js/scriptAdmin.js' type='text/javascript'></script>"; if (isset($_POST['adminLogBtn'])){ $pwHash = password_hash("A6hTYqBQ9ug", PASSWORD_DEFAULT); //$pwHash = "$2y$10$G175h4oBdNp3MlxSvH0Br./WASbhwR.m/RvmeV5on9TOpyrOWzJce"; $entLog = "Temp001"; if($_POST['entLog'] == $kerIsm && password_verify($_POST['passw'], $pwHash) == true){ $_SESSION['ADMIN'] = 1; $topContent = $adminContent; } else { echo "<p style='text-align:center; margin:50px;'>Не верны логин или пароль. <br><a href='/admin/' target='_self'>Попробуйте ещё раз.</a></p>"; } } elseif (isset($_SESSION['ADMIN'])){ $topContent = $adminContent; } else { $titleName = ""; $description = ""; $topContent = "<form action='/admin/' method='POST' name='adminEnt' id='adminEnt'><input required type='text' name='entLog' id='entLog' placeholder='Логин' maxlength='40'><input required type='password' name='passw' id='passw' placeholder='Пароль' maxlength='40'><input type='submit' value='Войти' name='adminLogBtn' id='adminLogBtn'></form>"; } ?> А на второй странице к переменной $adminContent присваивается длинная строка с HTML-кодом. Можно ли эту строку переделать на нормальный? И, раз уж привёл данный код, хотел бы спросить насчёт паролей, хотя тема другая. Как сохранить КЭШ пароля, если он каждый раз меняется? Хотел присвоить к переменной $pwHash кэш - не получается. Работает, если только из "открытого" пароля на месте КЭШ сделать и там же его проверить с помощью password_verify(). А по теме - не совсем смог решить проблему (то есть их там два оказалось). Теперь выводит весь список. Ошибку я понял, просто пока не могу придумать, как решить её более правильно. Есть список с именами людей, их телефонами, эл. почтами, датами их регистрации и т.п.... Есть форма поиска клиентов - там поля ввода для ID клиента (ключ БД), его имени, телефона, почты и т.д.. Я хотел сделать так, чтобы при вводе например, в поле ID цифры "6" и в поле телефон "1234" (оставив другие поля пустыми), и нажатии кнопки поиска, с помощью AJAX отправляется запрос, и возвращается список (в данном случае) клиента, у которого ID в базе - "6" и клиента, у которгого телефонный номер содержит цифры "1234". Но не продумал я то, что, как я понимаю, поля, которые не заполняются и остаются пустыми, проходят поиск с "LIKE" и подходят для всех клиентов в списке. Я могу фильтровать пустые данные в $_POST[''], принимаемым по AJAX, но как убрать их из запроса? Может, есть код MySQL, с помощью которого можно пропустить поиск, если в значении нет данных?
Нужно в самом запросе конструировать условие на основе пришедших данных. PHP: $query = "SELECT id, name, tel, email, FROM clients WHERE "; $id = $_POST['klId'] ?? ''; $x = ''; if ('' != $id) { $query .= $x . 'id = :id '; $x = 'OR '; // или AND ? } $name = trim($_POST['name'] ?? ''); if ('' != $name) { $query .= $x . 'name LIKE :name '; $x = 'OR '; // или AND ? } ..... $query .= 'ORDER BY name'; $stmtKlientS = $mb->prepare($query); if ('' != $id) { $stmtKlientS->bindValue(':id', (int) $id); } if ('' != $name) { $stmtKlientS->bindValue(':name', "%".$name."%"); } ....
Давай всё-таки предполагать что вычисления и вывод разделены. Даже если они в одном php файле, вывод лучше делать после добычи даных из базы и различных вычислений. Это путь к надежному и легко читаемому коду. Сообщения об ошибках без тегов html (!!!) копят в переменной-массиве, а в шаблоне выводят их в цикле, добавляя оформление - теги, стили и т.п. Ну и конечно шаблон может содержать условия типа "для админа выводим такую секцию". Это логика отображения, а не бизнес-логика. Так что в шаблоне это вполне уместно.
@Visman, спасибо большое! Всё работает! @artoodetoo, спасибо, но мне, похоже, придётся создать отдельную тему с этим вопросом - не могу я как-то нормально такой код сделать, с "открытым" HTML - знаний не хватает. Сделал бы, если бы в переменную можно было поместить условие. А это, как знаю, нельзя.