Форма поиска с одним или несколькими (несколькими) параметрами Параметры

#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[] не пусто, тогда ошибка — синтаксис SQL

3. Этот ответ предназначен для 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 , это делается автоматически.