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

#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 , он делает это автоматически.