#php #mysql
Вопрос:
Я ознакомился с основами, где я создал два файла, форму поиска, в которую пользователь вводит параметры поиска, и файл результатов, в котором проверяются введенные элементы. Для простоты мы обозначим файл формы поиска как 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;имя=xamp;колледж=y ИЛИ все элементы, если это необходимо).
Комментарии:
1. Не могли бы вы, пожалуйста, переформатировать свой код? Это очень трудно прочитать, когда у вас есть странные отступы php, открытые и закрытые теги, размещенные, по-видимому, случайным образом
2. Вы используете PDO или MySQLI?
3. @tivie очистил код и этикет вкладок . См.правки.
Ответ №1:
Создайте 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:
Если вы не собираетесь ничего менять в базе данных — вы просто выбираете — продолжайте и используйте 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 ( [Строка запроса] => ВЫБРАТЬ * ИЗ >
user_details
a ПРИСОЕДИНИТЬСЯ Кuser
b НА a.uid = b.id ГДЕ a.major = :major ) .. но, похоже, это ничего не дает.2. У вас есть петля
while($student = $stmt->fetch())
?3. Я понятия не имею, что я делал не так, но сейчас это работает @Barmar’а. Еще раз спасибо за вашу помощь, добрый сэр.
4. @Barмар Стоит добавить к вашему ответу на случай, если люди попробуют это сделать. Я не получал данные, возвращенные при отправке пустых полей формы. Возможно, это то, что я делал, но я добавил следующее в условия isset, и все хорошо, работает как заклинание.. if (isset($_GET[‘major’]) amp;amp; !пустой($_GET[‘major’])) { $wheres[] = ‘a.major = :major’; $params[‘:major’] = $_GET[‘major’];
5.
isset
является истинным до тех пор, пока переменная имеет какое-либо значение, даже если она имеет значение пустой строки. Обратите внимание , что этоempty
будет верно для переменной, установленной в0
, поэтому не используйте это для переменных, которые могут содержать числа. Кроме того, если вы используете!empty
, вам не нужно сначала тестироватьisset
, он делает это автоматически.