#php #sql #where-clause #and-operator
#php #Поиск #параметры #isset
Вопрос:
Я разобрался с основами, где я создал два файла: форму поиска, в которой пользователь вводит параметры поиска, и файл результатов, который выводит введенные элементы. Для простоты мы обозначим файл формы поиска как search.php и страница результатов в виде results.php .
search.php
<?php
if (!empty($_POST['id']) amp;amp; isset($_POST['id'])) {
header("Location: ?m=search.resultsamp;id=".$_POST['id']."");
} elseif (!empty($_POST['major']) amp;amp; isset($_POST['major'])) {
header("Location: ?m=search.resultsamp;major=".$_POST['major']."");
} elseif (!empty($_POST['college']) amp;amp; isset($_POST['major'])) {
header("Location: ?m=search.resultsamp;college=".$_POST['college']."");
} elseif (!empty($_POST['name']) amp;amp; isset($_POST['name'])) {
header("Location: ?m=search.resultsamp;name=".$_POST['name']."");
} elseif (!empty($_POST['id']) amp;amp; !empty($_POST['college']) amp;amp; !empty($_POST['major'])
amp;amp; isset($_POST['submit']) amp;amp; !empty($_POST['name'])) {
echo "<div class='alert alert-danger'>No students found. Please try different parameters.</div>";
}
?>
<h4>Search</h4>
<form method="POST">
<table width="100%">
<tr><td>ID:</td><td> <input type="text" name="id" class="form-control"></textarea></td></tr>
<tr><td>Name:</td><td> <input type="text" name="name" class="form-control"></textarea></td></tr>
<tr><td>Major:</td><td><select name="major" class="form-control"><option></option><?php echo majorSelect(); ?></select></td></tr>
<tr><td>College:</td><td><select name="college" class="form-control"><option></option><?php echo collegeSelect(); ?></select></td></tr>
<tr><td colspan="2"><input type="submit" name="submit" value="Search" class="btn btn-lrg btn-primary" style="margin-top:10px;"></td></tr>
</table>
</form>
results.php
<!-- Begin Search Parameters -->
<?php
if (isset($_GET['id'])) {
$students = $db->query("SELECT * FROM `user_details` a, `user` b WHERE a.uid = b.id AND a.uid = '".$_GET['id']."'");
while ($student = $students->fetch()) {
echo '
<tr>
<td>'.$student['uid'].'</td>
<td>'.$student['name'].'</td>
<td>'.$student['major'].'</td>
<td>'.$student['college'].'</td>
<td><a href="?m=profileamp;id='.$student['id'].'" style="display:block">View</a></td>
</tr>';
}
} elseif (isset($_GET['major'])) {
$students = $db->query("SELECT * FROM `user_details` a, `user` b WHERE a.uid = b.id AND a.major = '".$_GET['major']."'");
while ($student = $students->fetch()) {
echo '
<tr>
<td>'.$student['uid'].'</td>
<td>'.$student['name'].'</td>
<td>'.$student['major'].'</td>
<td>'.$student['college'].'</td>
<td><a href="?m=profileamp;id='.$student['id'].'" style="display:block">View</a></td>
</tr>';
}
} elseif (isset($_GET['college'])) {
$students = $db->query("SELECT * FROM `user_details` a, `user` b WHERE a.uid = b.id AND a.college = '".$_GET['college']."'");
while ($student = $students->fetch()) {
echo '
<tr>
<td>'.$student['uid'].'</td>
<td>'.$student['name'].'</td>
<td>'.$student['major'].'</td>
<td>'.$student['college'].'</td>
<td><a href="?m=profileamp;id='.$student['id'].'" style="display:block">View</a></td>
</tr>';
}
} elseif (isset($_GET['name'])) {
$name = $_GET['name'];
$students = $db->query("SELECT * FROM `user_details` a, `user` b WHERE a.uid = b.id AND b.name LIKE '%". $name . "%'");
while ($student = $students->fetch()) {
echo '
<tr>
<td>'.$student['uid'].'</td>
<td>'.$student['name'].'</td>
<td>'.$student['major'].'</td>
<td>'.$student['college'].'</td>
<td><a href="?m=profileamp;id='.$student['id'].'" style="display:block">View</a></td>
</tr>';
}
}
Итак, по сути, я хотел бы переписать вышесказанное, тогда как пользователь может ввести один или несколько параметров, и будет возвращен желаемый результат (например, как имя, так и колледж — amp;name=xamp;college= y ИЛИ все элементы, если это необходимо).
Комментарии:
1. Не могли бы вы переформатировать свой код? Это очень трудно читать, когда у вас странный отступ php открывает и закрывает теги, размещенные, по-видимому, случайным образом
2. Вы используете PDO или MySQLI?
3. @tivie очистил код и правила табуляции . Смотрите правки.
Ответ №1:
Это проще всего сделать при использовании PDO, а не mysqli, в качестве API базы данных.
Создайте WHERE
предложение динамически. Мой рекомендуемый подход заключается в том, чтобы помещать каждое условие в массив, а затем использовать implode()
для объединения всех условий, соединяя их с AND
или OR
, как вы предпочитаете.
$wheres = array();
$params = array();
if (!empty($_GET['id'])) {
$wheres[] = 'a.uid = :uid';
$params[':uid'] = $_GET['id'];
}
if (!empty($_GET['major'])) {
$wheres[] = 'a.major = :major';
$params[':major'] = $_GET['major'];
}
if (!empty($_GET['name'])) {
$wheres[] = 'b.name LIKE :name';
$params[':name'] = '%'.$_GET['name'].'%';
}
// And so on for all parameters
$sql = "SELECT *
FROM user_details AS a
JOIN user AS b ON a.uid = b.id";
if (!empty($wheres)) {
$sql .= " WHERE " . implode(' AND ', $wheres);
}
$stmt = $db->prepare($sql);
$stmt->execute($params);
Затем отобразите результаты, как в исходном коде.
while ($student = $stmt->fetch()) {
...
}
Комментарии:
1. Спасибо за вашу помощь. Смотрите мой комментарий к его сообщению ниже. Я считаю, что я почти на месте, но делаю что-то не так?
2. Я использую mysqli, я пробовал этот код, но когда
$wheres[]
пусто, я получаю ошибкуexecute() expects 0 params
, а когда$wheres[]
не пусто, тогда ошибка — синтаксис SQL3. Этот ответ предназначен для PDO, а не для mysqli. С mysqli это не так просто.
Ответ №2:
Если вы не собираетесь ничего менять в базе данных — вы просто выбираете — продолжайте и используйте GET вместо POST . Преимущество этого заключается в том, что он позволит вам сохранить URL-адрес в качестве строки поиска. Вы также можете обновить поиск без получения предупреждения о повторной отправке. Вы просто хотите убедиться, что вы параметризовали свои значения, прежде чем отправлять их в базу данных. Обычно я отправляю эти значения с помощью функций очистки, таких как регулярное выражение, которое гарантирует, что у вас есть только буквы, если вы ожидаете букв, или цифры, если вы ожидаете чисел.
На той же странице (весь поиск): (Я просто обрисую это для вас.)
<form action="<?= $_SERVER["REQUEST_URI"]; ?>" method="GET">
<input name="major" value="<?= $_GET["major"]; ?>" />
<select name="college">
<option value="1" <?PHP if( $_GET["college"] == 1 ) echo 'selected="true"'; ?>>Business</option>
</select>
</form>
<?PHP
if( ! empty( $_GET ) ){
if (isset($_GET['major'])) {
$wheres[] = 'a.major = :major';
$params[':major'] = $_GET['major'];
}
if (isset($_GET['name'])) {
$wheres[] = 'b.name LIKE :name';
$params[':name'] = '%'.$_GET['name'].'%';
}
// And so on for all parameters
$sql = "SELECT *
FROM user_details AS a
JOIN user AS b ON a.uid = b.id";
if (!empty($wheres)) {
$sql .= " WHERE " . implode(' AND ', $wheres);
}
$stmt = $db->prepare($sql);
$stmt->execute($params);
}
?>
Теперь вы можете отображать свои данные.
редактировать: я написал вторую половину ответа, а затем он написал 2-ю половину, поэтому я просто включил ее…
Кроме того, следующим уровнем сложности в этом было бы извлечь PHP из файла поиска и поместить его в другой файл. Когда вы нажимаете кнопку поиска в своей форме, вы используете AJAX для вызова элементов PHP. Затем PHP-файл вернет результаты через Ajax. Вы можете вернуть либо предварительно отформатированный HTML, либо JSON и позволить чему-то вроде jQuery отобразить его для вас.
Комментарии:
1. Теперь запрос генерируется динамически. Потрясающе. Возможно, я делаю что-то не так, потому что print_r выдает мне: Объект PDOStatement ( [queryString] => ВЫБЕРИТЕ * ИЗ
user_details
СОЕДИНЕНИЯuser
b В.uid = b.id ГДЕ a.major = :major) .. но, похоже, это ничего не дает.2. У вас есть цикл
while($student = $stmt->fetch())
?3. Я понятия не имею, что я делал не так, но сейчас это работает @Barmar. Еще раз спасибо за вашу помощь, добрый сэр.
4. @Barmar Стоит добавить к вашему ответу на случай, если люди попробуют это. Я не получал данные, возвращаемые при отправке пустых полей формы. Возможно, это то, что я делал, но я добавил следующее к условиям isset, и все хорошо, работает как шарм .. if (isset($_GET[‘major’]) amp;amp; !empty($_GET [‘major’])) { $wheres[] = ‘a.major = :major’; $params[‘:major’] = $_GET[‘major’];
5.
isset
имеет значение true, если для переменной задано любое значение, даже если для нее задана пустая строка. Обратите внимание, что этоempty
будет верно для переменной, установленной на0
, поэтому не используйте это для переменных, которые могут содержать числа. Кроме того, если вы используете!empty
, вам не нужно сначала тестироватьisset
, это делается автоматически.