Php 使用4个不同的选择框搜索数据库

Php 使用4个不同的选择框搜索数据库,php,mysql,sql,search,Php,Mysql,Sql,Search,我要创建一个相当复杂的WHERE语句。我已经搜索了很多网站来寻找答案,但我的页面仍然没有显示任何内容 业务需求:使用4个不同的下拉列表,通过选择其中一个、全部或四者的任意组合,从数据库中获取结果 以下是searchInstructors.php文件的php代码: <?php $dsn = 'mysql: host=localhost; dbname=name'; $user = 'user'; $password = 'pa

我要创建一个相当复杂的WHERE语句。我已经搜索了很多网站来寻找答案,但我的页面仍然没有显示任何内容

业务需求:使用4个不同的下拉列表,通过选择其中一个、全部或四者的任意组合,从数据库中获取结果

以下是searchInstructors.php文件的php代码:

         <?php
        $dsn = 'mysql: host=localhost; dbname=name';
        $user = 'user';
        $password = 'pass';
        try {
        $pdo = new PDO($dsn, $user, $password);
        $pdo ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOException $e) {
        echo 'Connection failed: ' . $e->getMessage();
        }

         if(isset($_GET['semester'])){
            $semester = $_GET['semester'];  
        }else{
            $semester = "Not Selected";
        }
        if(isset($_GET['year'])){
            $year = $_GET['year'];  
        }else{
            $year = "Not Selected";
        }
        if(isset($_GET['coursePrefix'])){
            $coursePrefix = $_GET['coursePrefix'];  
        }else{
            $coursePrefix = "Not Selected";
        }
        if(isset($_GET['courseNumber'])){
            $courseNumber = $_GET['courseNumber'];  
        }else{
            $courseNumber = "Not Selected";
        }

        echo "<table class='tg' width='100%'>";
        echo "<tr>

                <th><strong>Course</strong></th>        
                <th><strong>Name</strong></th>
                <th><strong>Email/Phone</strong></th>
                <th><strong>Semester</strong></th>
                <th><strong>Institution</strong></th>
        </tr>";
        $sql="SELECT courses.coursePrefix  courses.courseNumber,   facultyContact.firstName, facultyContact.lastName, facultyContact.email, facultyContact.phone, facultyContact.institution, courses.semester, courses.year
        FROM courses
        LEFT JOIN facultyContact 
        ON courses.ID=facultyContact.ID
        WHERE (courses.semester LIKE :semester AND courses.year LIKE :year)
OR (courses.semester LIKE :semester AND courses.coursePrefix LIKE :coursePrefix)
OR (courses.semester LIKE :semester AND courses.courseNumber LIKE :courseNumber) 
OR (courses.year LIKE :year AND courses.coursePrefix LIKE :coursePrefix)
OR (courses.year LIKE :year AND courses.courseNumber LIKE :courseNumber)
OR (courses.coursePrefix LIKE :coursePrefix AND courses.courseNumber LIKE :courseNumber)
OR (courses.semester LIKE :semester AND courses.year LIKE :year AND courses.coursePrefix LIKE :coursePrefix)
OR (courses.semester LIKE :semester AND courses.year LIKE :year AND courses.courseNumber LIKE :courseNumber)
OR  (courses.semester LIKE :semester AND courses.year LIKE :year AND courses.coursePrefix LIKE :coursePrefix AND courses.courseNumber LIKE :courseNumber)
        ORDER BY facultyContact.lastName";

        $stmt = $pdo->prepare($sql);
        $stmt->bindParam(':semester', $semester, PDO::PARAM_STR);
        $stmt->bindParam(':year', $year, PDO::PARAM_INT);
        $stmt->bindParam(':coursePrefix', $coursePrefix, PDO::PARAM_INT);
        $stmt->bindParam(':courseNumber', $courseNumber, PDO::PARAM_INT);
        $stmt->execute();
        $total = $stmt->rowCount();
        while ($row = $stmt->fetchObject()) {

           echo "<tr>
                <td>{$row->coursePrefix}<br /> {$row->courseNumber} </td>
                <td>{$row->firstName} {$row->lastName}</td>
                <td>{$row->email} <br />{$row->phone}</td>
                <td>{$row->semester} {$row->year} </td>
                <td>{$row->institution} </td>";
        }
        if (empty($total)) { 
            echo '<td colspan="5">No results found for your selection<br>' .
        '<strong>'. $semester . ' - ' . $year. ' - ' .  $coursePrefix. ' - ' .     $courseNumber . '</strong></td>'; 
        } else {
            echo implode($total);
        }

        $pdo = null;
        echo "</tr></table>";
           ?>
它也不起作用。当WHERE语句是all AND AND all OR时,我可以使它工作。它将使用两个下拉列表和一个或类似的选项:

courses.semester LIKE :semester AND courses.year LIKE :year OR 
courses.semester LIKE :semester AND courses.coursePrefix LIKE :coursePrefix OR
courses.semester LIKE :semester AND courses.courseNumber LIKE :courseNumber
我曾想过创建视图,只是让每个下拉式下拉视图,但有太多的组合,当添加新课程时,我将不得不重做视图。
是否可以创建一个WHERE语句或查询,该语句或查询将以任意组合从4个下拉列表中获取输入?

让PHP动态地构建它,而不是为学期、年份、前缀和数字的每个可能组合手动创建SQL

定义要在SQL中使用的所有变量

$inputs = array(
    'semester'      => false,
    'year'          => false,
    'coursePrefix'  => false,
    'courseNumber'  => false
);
检查$\u GET数组中是否存在变量

foreach ( $inputs as $k => $v ) {
    if ( isset($_GET[$k]) ) {
        $inputs[$k] = $_GET[$k];
    }
}
在SQL中动态构建where子句。注意:我的代码只是一个起点,并没有完成您需要的一切,比如绑定。你得自己做

$sql = 'SELECT your_columns FROM courses LEFT JOIN your_joins ';
$where = array();
foreach ( $inputs as $k => $v ) {
    if ( $v !== false ) {
        $where[$k] = 'courses.'.$k.' = :'.$k;   
    }
}
if ( sizeof($where) > 0 ) {
    $sql .= 'WHERE '.implode(' AND ', $where);  
}
$sql .= ' ORDER BY some_columns';
现在使用一些URL,例如

semester=Summer&year=2009&coursePrefix=PLA
semester=Summer&year=2009
semester=Summer
请注意,代码如何不知道或不关心给定的参数组合


一旦你解决了这个问题,添加选项允许用户指定和/或在参数之间-或允许他们选择多个参数,例如复选框是非常容易的。

因此,在花了很多时间研究之后,我有了可以工作的代码。因此,这是为所有其他人,必须做一些复杂的事情

<?php
$dsn = 'mysql: local host; dbname=dbName';
$user = 'user';
$password = 'pass;
try {
$pdo = new PDO($dsn, $user, $password);
$pdo ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
try{
    $query = "SELECT courses.coursePrefix, courses.courseNumber, facultyContact.firstName, facultyContact.lastName, facultyContact.email, facultyContact.phone, facultyContact.institution, courses.semester, courses.year
FROM courses 
LEFT JOIN facultyContact 
ON courses.ID=facultyContact.ID ";
$cond = array();
$params = array();

 if( isset($_GET['semester']) && !(empty($_GET['semester'])) ){  
    $cond[] = " courses.semester LIKE '". $_GET['semester']."'";
    $params[] = $semester;

}
if(isset($_GET['year']) && !(empty($_GET['year'])) ){  
    $cond[] = " courses.year LIKE '". $_GET['year']."'";
    $params[] = $year;
}
if(isset($_GET['coursePrefix']) && !(empty($_GET['coursePrefix'])) ){
    $cond[] = " courses.coursePrefix LIKE '". $_GET['coursePrefix']."'";
    $params[] = $coursePrefix;
}
if(isset($_GET['courseNumber']) && !(empty($_GET['courseNumber'])) ){
    $cond[] = " courses.courseNumber LIKE '". $_GET['courseNumber'] ."'";
    $params[] = $courseNumber;
}
if (count($cond)) {
    $query .= ' WHERE ' . implode(' AND ', $cond);
}
$query.= "ORDER BY facultyContact.lastName, facultyContact.firstName";

$stmt = $pdo->prepare($query);
$stmt->execute($params);

echo "<table class='tg' width='100%'>";
echo "<tr>

        <th><strong>Course</strong></th>        
        <th><strong>Name</strong></th>
        <th><strong>Email/Phone</strong></th>
        <th><strong>Semester</strong></th>
        <th><strong>Institution</strong></th>
</tr>";

$total = $stmt->rowCount();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) {

   echo "<tr>    
        <td>" . $row['coursePrefix'] . " ". $row['courseNumber'] . "</td>" .

        "<td>" . $row['firstName'] . " " . $row['lastName'] . "</td>" .

        "<td>" . $row['email']. "<br />" . $row['phone'] ."</td>" .

        "<td>" . $row['semester'] ." " . $row['year'] . "</td>" .

        "<td>" . $row['institution'] . "</td></tr>";
}
//user error message for no results
if (empty($total)) { 
    echo '<td colspan="5">No results found for your selection<br>' .
'<strong>'. $_GET['semester'] . ' - ' . $_GET['year']. ' - ' .  $_GET['coursePrefix'] . ' - ' . $_GET['courseNumber'] . '</strong></td>'; 
} else {
    echo implode($total);
}
} catch (PDOException $e) {
    $error_messageALL = $e->getMessage();
    echo "DB error: " . $error_messageALL;  

    }

    $pdo = null;
    echo "</tr></table>";
       ?>

你肯定喜欢huhwhy,为什么不在每个下拉列表旁边放置AND和OR下拉列表,这样用户就可以决定是AND还是ORoh,我现在得到任意组合的东西了。如果未选择任何值,请不要将字段添加到WHERE子句中…完成。我可以在此处看到绑定,但没有转义或列名的白名单。也许值得添加一个注释或依赖我的注释!要说这段代码的用户需要注意这里的SQL注入。列在$inputs中有明确的定义,并且不会被任何用户提交的数据修改。不过,我会更进一步,创建一个更复杂的数组来保存PDO绑定使用的数据类型!啊,太好了-我没看到这已经是白名单了!然而,some_columns位并没有实现,我认为任何将此作为起点的人都应该小心。使用$\u GET Safe可能是一个雷区。
semester=Summer&year=2009&coursePrefix=PLA
semester=Summer&year=2009
semester=Summer
<?php
$dsn = 'mysql: local host; dbname=dbName';
$user = 'user';
$password = 'pass;
try {
$pdo = new PDO($dsn, $user, $password);
$pdo ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
try{
    $query = "SELECT courses.coursePrefix, courses.courseNumber, facultyContact.firstName, facultyContact.lastName, facultyContact.email, facultyContact.phone, facultyContact.institution, courses.semester, courses.year
FROM courses 
LEFT JOIN facultyContact 
ON courses.ID=facultyContact.ID ";
$cond = array();
$params = array();

 if( isset($_GET['semester']) && !(empty($_GET['semester'])) ){  
    $cond[] = " courses.semester LIKE '". $_GET['semester']."'";
    $params[] = $semester;

}
if(isset($_GET['year']) && !(empty($_GET['year'])) ){  
    $cond[] = " courses.year LIKE '". $_GET['year']."'";
    $params[] = $year;
}
if(isset($_GET['coursePrefix']) && !(empty($_GET['coursePrefix'])) ){
    $cond[] = " courses.coursePrefix LIKE '". $_GET['coursePrefix']."'";
    $params[] = $coursePrefix;
}
if(isset($_GET['courseNumber']) && !(empty($_GET['courseNumber'])) ){
    $cond[] = " courses.courseNumber LIKE '". $_GET['courseNumber'] ."'";
    $params[] = $courseNumber;
}
if (count($cond)) {
    $query .= ' WHERE ' . implode(' AND ', $cond);
}
$query.= "ORDER BY facultyContact.lastName, facultyContact.firstName";

$stmt = $pdo->prepare($query);
$stmt->execute($params);

echo "<table class='tg' width='100%'>";
echo "<tr>

        <th><strong>Course</strong></th>        
        <th><strong>Name</strong></th>
        <th><strong>Email/Phone</strong></th>
        <th><strong>Semester</strong></th>
        <th><strong>Institution</strong></th>
</tr>";

$total = $stmt->rowCount();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) {

   echo "<tr>    
        <td>" . $row['coursePrefix'] . " ". $row['courseNumber'] . "</td>" .

        "<td>" . $row['firstName'] . " " . $row['lastName'] . "</td>" .

        "<td>" . $row['email']. "<br />" . $row['phone'] ."</td>" .

        "<td>" . $row['semester'] ." " . $row['year'] . "</td>" .

        "<td>" . $row['institution'] . "</td></tr>";
}
//user error message for no results
if (empty($total)) { 
    echo '<td colspan="5">No results found for your selection<br>' .
'<strong>'. $_GET['semester'] . ' - ' . $_GET['year']. ' - ' .  $_GET['coursePrefix'] . ' - ' . $_GET['courseNumber'] . '</strong></td>'; 
} else {
    echo implode($total);
}
} catch (PDOException $e) {
    $error_messageALL = $e->getMessage();
    echo "DB error: " . $error_messageALL;  

    }

    $pdo = null;
    echo "</tr></table>";
       ?>