douchanxiu5636 2016-04-21 11:03
浏览 47
已采纳

使用PDO从多个领域进行高级搜索

I'm trying to make advanced search form with PDO but can't understand how to pass bound variables in prepared statements.

I'm not even sure that this is right approach and will need some help to finish it.

So on the form I have one input field which search in 3 columns + two more dropdowns which are additions search but not mandatory. This is the form:

<form class="form-horizontal" name="form-horizontal" action="" method="post" role="form">     
    <div class="container-fluid">
        <div class="row">        
            <h2>Enter the text which you want to search</h2>            
                  <div class="col-md-8">
                    <div id="custom-search-input">
                        <div class="input-group col-md-12">
                                <input type="text" class="form-control input-lg" placeholder="Search in title, description or keywords" name="tdkey"/>
                                <span class="input-group-btn">
                                    <button class="btn btn-info btn-lg" type="submit" name="submit">
                                        <i class="glyphicon glyphicon-search"></i>
                                    </button>
                                </span>
                        </div>
                    </div>
                    </div>
                    <div class="col-md-4">
                      <button type="button" class="btn btn-primary btn-lg" data-toggle="collapse" data-target="#filter-panel">
                        <span class="glyphicon glyphicon-cog"></span> Advanced Search
                    </button>               
                </div>

            </div>          
      </div>
          <div id="filter-panel" class="collapse filter-panel">                
        <div class="container-fluid">
          <div class="row">
            <div class="col-md-3">
                <h4>Select by Category</h4>
                    <?php 
                        $pdo = Database::connect();
                        $sql="SELECT field_name FROM form_fields WHERE group_id=6";                         
                        echo '<select class="form-control" name="upload_category" id="select2">';
                        foreach ($pdo->query($sql) as $upload_category){
                            echo '<option value='.$upload_category['field_name'].'>'.$upload_category['field_name'].'</option>';                                
                        }
                        echo '</select>';
                    ?>
            </div> 
            <div class="col-md-3">
                <h4>Select by Program</h4>
                    <?php 
                        $pdo = Database::connect();
                        $sql="SELECT field_name FROM form_fields WHERE group_id=1";                         
                        echo '<select class="form-control" name="upload_program" id="select2">';
                        foreach ($pdo->query($sql) as $row_program){

                            echo '<option value='.$row_program['field_name'].'>'.$row_program['field_name'].'</option>'; 
                        }
                        echo '</select>';
                    ?>
            </div>

And this is my try in PHP part

if(isset($_POST["submit"])){
            $query = "";
            $tdkey = $_POST["tdkey"];
            $upload_program = $_POST["upload_program"];
            $upload_category = $_POST["upload_category"];

            if(isset($tdkey)){ // if tdkey is set select here
                $query = "SELECT * FROM document_upload WHERE upload_title LIKE :search_title OR upload_description LIKE :search_description OR upload_keywords LIKE :search_keywords";             

                if(isset($upload_category)){ // also if category is set add this to query
                    $query .= "AND upload_category LIKE :search_category";
                }
                if(isset($upload_program)){ // also if program is set add this
                    $query .= "AND upload_program LIKE :search_program";
                }
            } else if (isset($upload_category)){ // if tdkey isn't set go here 
                $query = "SELECT * FROM document_upload WHERE upload_category LIKE :search_category";
                if(isset($upload_program)){ // add this also if program is set to category
                    $query .= "AND upload_program LIKE :upload_program";
                }
            } else if (isset($upload_program)){ // if only country is set go here
                $query = "SELECT * FROM document_upload WHERE upload_program LIKE :search_program";
            } 
                $stmt = $pdo->prepare($query);
                $stmt->bindValue(":search_title", "%" . $tdkey . "%");
                $stmt->bindValue(":search_description", "%" . $tdkey . "%");
                $stmt->bindValue(":search_keywords", "%" . $tdkey . "%");                                       
                $stmt->bindValue(":search_category", "%" . $upload_category . "%");
                $stmt->bindValue(":search_program", "%" . $upload_program . "%");


                $stmt->execute();                               
                $result = $stmt->fetchAll();            
                if ($stmt->rowCount() > 0) { 
                   //results
                }

The error is

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens Do I need after each query to bound variables? Or there is more "intelligent" way to do this?

Main goal is to search from field where is text, description and keywords and if need to add some program or category. And I think the best approach is like this what I found while I do some research on google - dynamically creating sql ..

  • 写回答

1条回答 默认 最新

  • douhao9203 2016-04-21 11:24
    关注

    You have some params that are only required for certain conditions and then are trying to bind them all regardless.

    It might be worth setting up a params array and adding params that you need in the relevant conditions.

    You can use a foreach to bind them to the statement.

    Something like:

    $query = '';
    $params = [];
    
    if(isset($search_term_value)){
      $query= 'SELECT * FROM example WHERE term LIKE :search_term';
      $params['search_term'] = '%'.$search_term_value.'%';
    }
    
    $stmt = $pdo->prepare($query);
    foreach($params as $key=>$value){
      $stmt->bindValue(':'.$key, $value);
    }
    $stmt->execute();  
    

    Also, I'm pretty sure

    AND upload_program LIKE :upload_program 
    

    should read

    AND upload_program LIKE :search_program
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错