构建动态PDO Mysql查询

时间:2014-10-18 14:47:18

标签: php mysql pdo

我尝试使用以下三个选项过滤结果列表:

主要类别,子类别和搜索

两个类别选项是下拉列表,搜索是文本框。

到目前为止,这是我的代码:

files.php

    if (!isset($_GET['filter'])){
        $_GET['filter'] = "";
    }
    if (!isset($_GET['search'])){
        $_GET['search'] = "";
    }
    if (!isset($_GET['subcategory'])){
        $_GET['subcategory'] = "";
    }

//过滤结果的表单:

<form method="get">
Category: <select name="filter">
    <option <?php if(!isset($_GET['filter'])){echo 'selected';} ?> value="">-- Select Category --</option>
    <option <?php if($_GET['filter'] == "1") {echo 'selected';} ?> value="1">View Vehicles Only</option>
    <option <?php if($_GET['filter'] == "2") {echo 'selected';} ?> value="2">View Lighting Equiptment</option>
</select><br /><br />
<?php 


        if(isset($_GET['filter'])){
            if($_GET['filter'] != ""){
                echo 'SubCategory:  <select name="subcategory">';
                    $sub_categories = getsubcategories($_GET['filter']);
                    foreach ($sub_categories as $cat){
                        echo '<option value = "'.$cat['cat_id'].'">'.$cat['cat_name'].'</option>';
                    }
                echo '</select><br /><br />';
            }
        }

    ?>
    Search Files: <input type="text" name="search" <?php if(isset($_GET['search'])){echo 'value="'.$_GET['search'].'"';}?> placeholder=" Enter a search term..." />
    <br /><br /><center><input type="submit" class="btn btn-default" value="Update Results"/> <a href="files.php" class="btn btn-default">Reset Filters</a></center>
    </form>

//调用函数来检索结果:

$files = getbycategory($_GET['filter'], $_GET['search'], $_GET['subcategory']);

//循环结果:

foreach($files as $file){

echo'<div class="col-lg-" id="file-'.$file['part_id'].'">
        <div class="file-list-item first" id="">';
            if ($file['image_url'] == "")
            {
                echo '<img class="file-image" height="120px" width="180px" src="'.baseurl.'/resources/img/no-image.png" />';
            } else {
                echo '<img class="file-image" height="120px" width="180px" src="'.$file['image_url'].'" />';
            }   

            echo '
            <div class="file-text">
                <h3><strong>'.$file['part_name'].'</strong></h3>
                Submitted by: '.$file['submitter'].'<br/>
                Author: '.$file['author'].'<br />
                Category: '.ucfirst($file['subcategory']).'<br />
                Description: '.substr($file['description'],0,45).'...
            </div>
            <div class="download">
                <a target="_blank" href="'.$file['download_url'].'" class="btn-success btn btn-default">Download</a>
                <a href="'.baseurl.'/broken.php?id='.$file['part_id'].'" class="btn btn-default">Report as Broken</a><br /><br />';
                    if($file['is_broken']){
                        echo '<span class="broken"><i data-toggle="tooltip" data-placement="left" id="broken" title="This file has been reported as broken by \'Alcon H\' and is awaiting review." class="fa fa-warning fa-2x"></i></span>';
                    }


                echo '

            </div>
        </div>
    </div>';
};

file_functions.php

//这是检索结果的函数:

function getbycategory($category, $search, $subcategory){

    global $db;

    $sm = $db->prepare("SELECT * FROM parts WHERE main_category = :category AND active = 1 AND subcategory = :subcategory AND part_name LIKE :search");

        if ($category == ""){
            $category = '%';
            $sm->bindParam(":category", $category, PDO::PARAM_STR);    
        } else {
            $sm->bindParam(":category", $category, PDO::PARAM_STR);
        }

        if ($subcategory ==""){
            $subcategory = '%';
            $sm->bindParam(":subcategory", $subcategory, PDO::PARAM_STR);
        } else {
            $sm->bindParam(":subcategory", $subcategory, PDO::PARAM_STR);
        }

        if ($search == ""){
        $search = '%'.$search.'%';
        } else {
        $sm->bindParam(":search", $search, PDO::PARAM_STR);
        }

    $sm->execute();
    return $sm->fetchAll();
    }

我收到的错误是:

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens' in /var/www/html/partsdb/resources/file_functions.php:74\nStack trace:\n#0 /var/www/html/partsdb/resources/file_functions.php(74): PDOStatement->execute()\n#1 /var/www/html/partsdb/files.php(18): getbycategory('', '', '')\n#2 {main}\n  thrown in /var/www/html/partsdb/resources/file_functions.php on line 74, referer: http://localhost/partsdb/files.php

file_functions.php的第74行就是它的执行位置。

谁能看到我哪里出错了?

2 个答案:

答案 0 :(得分:1)

如果只在搜索字符串为空时才会发生这种情况,那是因为:

    if ($search == ""){
        $search = '%'.$search.'%';
    } else {
        $sm->bindParam(":search", $search, PDO::PARAM_STR);
    }

仅在$search变量不是空字符串时才绑定参数。要修复它,您可以将其修改为:

    if ($search == ""){
        $search = '%'.$search.'%';
    } 

    $sm->bindParam(":search", $search, PDO::PARAM_STR);

因此它始终将准备好的语句与搜索字段绑定在一起。虽然如果空的$ search将被替换为字符串%%,因此只返回等于字符串%%的值,这似乎有点奇怪,因为我相信你更喜欢那里的LIKE语句,尽管是一个与此不同的问题。

答案 1 :(得分:0)

首先将Ternary operatorisset()一起使用。

$category = isset($_GET["category"]) ? $_GET["category"] : "";

声明一个数组来保存参数。

$params = array();

然后将查询存根设置为变量。

$sql = "SELECT * FROM parts ";

将标志设置为0以从WHERE切换为AND以获取2个或更多参数

开始构建查询的其余部分,增加$flag$params数组添加参数

if($category != ""){
        $sql .= " WHERE main_category = ?";
        $params[] = $category;
        $flag++; 
        }

如果标志&gt; 0使用AND而不是WHERE

if($search != ""){
       if($flag > 0){
            $sql .= " AND search = ?";

       }else{
            $sql .= " WHERE search = ?";
       }
       $params[] =$search;
       $flag++;

使用&#34;懒惰&#34;绑定将数据传递给执行。

$sm->execute($params);

最终代码。

<?php
$category = isset($_GET["category"]) ? $_GET["category"] : "";
$search = isset($_GET['search']) ? $_GET['search'] : "";
$subcategory = isset($_GET['subcategory']) ? $_GET['subcategory'] : "";
$params = array();

function getbycategory($category, $search, $subcategory){


    global $db;
    $sql = "SELECT * FROM parts ";
    $flag = 0;
    if($category != ""){
        $sql .= " WHERE main_category = ?";
        $params[] = $category;
        $flag++; 
        }
    if($search != ""){
       if($flag > 0){
            $sql .= " AND search = ?";

       }else{
            $sql .= " WHERE search = ?";
       }
       $params[] =$search;
       $flag++;
        }   
    if($subcategory != ""){
       if($flag > 0){
            $sql .= " AND subcategory = ?";

       }else{
            $sql .= " WHERE subcategory = ?";
       }
       $params[] = $subcategory;
       }   

    echo   $sql; //Remove after testing  
    print_r($params);//Remove after testing     
    $sm = $db->prepare($sql);  
    $sm->execute($params);
    return $sm->fetchAll();
}   
getbycategory($category, $search, $subcategory);



    } 

阅读您的代码我看到$category = '%';如果您需要LIKE而不是=,则需要先准备全文字。

$category = "%$category%";