【问题标题】:Database column based record filtering not working using auto-complete search PHP基于数据库列的记录过滤无法使用自动完成搜索 PHP
【发布时间】:2015-05-07 10:54:19
【问题描述】:

我在我的网站中集成了自动完成搜索,用户输入关键字并根据它查看记录。

假设,如果我编写邮政编码,它只会过滤来自邮政编码字段的数据。接下来,如果用户键入地址,例如 121 North West,那么脚本会自动选择匹配 121 North West 的记录。此外,对于街道也是如此,如果用户输入像 cedar Lane 这样的街道名称,那么它只会从数据库字段 street 中获取记录。

我在搜索所有字段的记录时遇到问题,因此我无法从数据库中获取正确的列表。

我关注的参考站点是http://www.trulia.com,这里按预期工作。我希望在我的网站上使用相同的内容,它可以正常工作,但与我预期的不同。

我的 PHP 代码:

<?php
$searchKeyword  = $_REQUEST['keyword'];

$searchQ    =   "SELECT zip, ste, st, st_num, town, addr FROM tbl_property WHERE (zip = '$searchKeyword' OR ste like '%$searchKeyword%' OR town like '%$searchKeyword%' OR addr like '%$searchKeyword%') GROUP BY zip LIMIT 0,5";
$queryRec   = mysql_query($searchQ);
$recSet     = mysql_num_rows($queryRec);
echo "<div id='fetchRecs'><ul>";
if($recSet>0){
    while($row = mysql_fetch_array($queryRec)) { 
        echo '<li>'.$row['addr'].', '.$row['town'].', '.$row['ste'].', '.$row['zip'];?></li>
    <?php
            }
        }else{
    echo "<li>No Records Found</li>";       
    }
echo "</ul></div>";

我只是想如果用户写 123,列表显示像 1234,1245,并且像列表一样只显示 zip 列中的邮政编码。

同样,如果用户写 123 cedar,它会选择类似于 123 cedar 的列表,仅表示它来自 street 列。

P.S:我只有一个文本字段,可以在其中输入关键字,例如:http://www.trulia.com

PS:我的问题还没有解决,如果有人有任何有用的信息,请分享。也许它也适用于其他人。

【问题讨论】:

    标签: php mysql search full-text-search full-text-indexing


    【解决方案1】:

    首先,请原谅我的错误。

    好的,我改变了一些东西,现在可以工作了:

    //Filter:
    <?php
    
      if (isset($_REQUEST['field']) && isset($_REQUEST['keyword'])) {
        $field = $_REQUEST['field'];
        $keyword = $_REQUEST['keyword'];
      }else{
        $field = null;
        $keyword = null;
      }
      $query = "SELECT * FROM tbl_property";
      $where = "";
      switch ($field) {
          case 'zipCode':
              $where = " WHERE zip like '" . $keyword . "%'";
              break;
          case 'addr':
              $where = " WHERE addr like " . $keyword . "%";
              break;
          case 'city':
              $where = " WHERE city like " . $keyword . "%";
              break;
      }
      $query = $query . $where;
    
      $db = new mysqli('localhost', 'user', 'password', 'db');
      if ($db->connect_errno > 0){
        die($db->connect_error);
      }
    
      $result = $db->query($query)
    ?>
    
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>Searcher</title>
      <link rel="stylesheet" href="">
    </head>
    <body>
    
        <section id="searcher">
          <form action="" method="post">
          <input type="text" name="keyword" id="keyword"           />
          <input type="hidden" name="field" id="field" value="all" />
          <div id="lists">
            <ul></ul>
          </div>
          </form>
        </section>
    
        <section id="results">
            <table>
              <caption>Results</caption>
              <thead>
                <tr>
                  <th>Zip</th>
                  <th>Address</th>
                  <th>City</th>
                </tr>
              </thead>
              <tbody>
                <?php while($row = $result->fetch_assoc()){ ?>
                <tr>
                  <td><?php echo ($row['zip']); ?></td>
                  <td><?php echo ($row['addr']); ?></td>
                  <td><?php echo ($row['city']); ?></td>
                </tr>
                <?php } ?>
              </tbody>
            </table>      
        </section>
    
        <script src="http://code.jquery.com/jquery-2.1.3.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
          $( "#keyword" ).keyup(function() {
            $.ajax({
                type: "POST",
                url: "req.php",
                data:{ key: $(this).val() },
                success: function(data){
                    //Show the data to the clients
                    //(in a div or a "select2" plugin)
                    if (data.locations.length > 0){
                      $('#lists ul').html('');
                      $.each(data.locations, function( key, location ) {
                          //iterate over locations
                          $('#lists ul').append( '<li data-field="' + location._type + '">' + location.value  + '</li>' );
                      });
    
                      //SetUp hidden default value while keyword change
                      //Form the JSON Response
                      $('#field').val(data.locations[0]._type);
                    }else{
                      $('#lists ul').html('No Results!');
                      $('#field').val('all');
                    }
                }
            });
          });
    
          $('#lists ul li').click(function(){
              $('#keyword').val($(this).html());
              $('#field').val($(this).parent().data('field'));
          });
        </script>
    
    </body>
    </html>
    
    <?php
      $db->close();
    ?>
    

    //req.php
    <?php
    $key = $_POST['key'];
    
    $data = array(
                  'locations' => array(),
                  'errors'=>array(),
                  'success'=> true
                  );
    
    header('Content-Type: application/json');
    
      $db = new mysqli('localhost', 'user', 'password', 'db');
    
    if($db->connect_errno > 0){
        $data['errors'][] = $db->connect_error;
        die(json_encode($data));
    }
    
    $query = "SELECT zip FROM tbl_property WHERE zip LIKE '" . $key . "%';";
    $zips = $db->query($query);
    
    $query = "SELECT city FROM tbl_property WHERE city LIKE '" . $key . "%';";
    $cities = $db->query($query);
    
    if($db->connect_errno > 0){
        $data['errors'][] = $db->connect_error;
        die(json_encode($data));
    }
    
    $index = 0;
    if ($zips){
      while($row = $zips->fetch_assoc()){
          $data['locations'][] = array(
              "value"=> $row['zip'],
              "altValue"=> null,
              "display"=> $row['zip'],
              "_type"=> "zipCode",
              "propertyIndex"=> "",
              "index"=> $index
          );
          $index = $index + 1;
      }
    }
    if ($cities){
      while($row = $cities->fetch_assoc()){
          $data['locations'][] = array(
              "value"=> $row['city'],
              "altValue"=> null,
              "display"=> $row['city'],
              "type"=> "city",
              "propertyIndex"=> "",
              "index"=> $index
          );
    
          $index = $index + 1;
      }
    }
    
    $db->close();
    
    header('Content-Type: application/json');
    echo json_encode($data);
    

    我没有对lists ul li 元素上的点击事件进行测试,因为我不知道你会做什么,而且是不太重要的部分。

    我希望这就是您想要的。 保持联系。

    【讨论】:

    • 首先,感谢您在修复方面的积极响应,现在代码对我有用。我必须说它是您为我开发的最优化和最有效的代码,因为它解决了我的所有问题。 :) 再次感谢你。 ;)
    【解决方案2】:

    更新


    这是来自http://www.trulia.com/的表格

    <div class="searchbox">
      <form id="searchbox_form" class="searchbox_form form man" method="get" action="/submit_search/" autocomplete="off">
        <div class="field man">
    
          <span class="select">
            <div id="homepage-select" class="selectPretty">
              <select id="search_options" class="h5 man txtL" name="display_select" data-previous-selection="for_sale">
                  <option value="for_sale">Buy</option>
                  <option value="for_rent">Rent</option>
                  <option value="sold">Recently sold</option>
              </select>
              <div class="selectDisplay btn btnLrg btnDefault rrn backgroundBasic pts plm">
                <span class="selectLabel h5">Buy</span>
                <span class="selectTrigger pts"><i class="iconDownOpen"></i></span>
              </div>
            </div>
          </span>
          <span class="text">
            <div style="display: none; top: 129px; left: 297.5px; width: 370px;" class="autosuggest_list"><ul><li class="location-get-me">Current Location</li></ul></div><input id="searchbox_form_location" type="text" name="search" class="searchbox_form_location searchInput text searchByLocation typeWeightNormal h5 man" value="" placeholder="Search by neighborhood, city, zip or address" autocomplete="off">
            <input type="hidden" name="locationId" value="">
            <input type="hidden" name="locationType" value="">
            <input type="hidden" name="tst" class="searchbox_form_type" value="h">
            <input type="hidden" name="ac_entered_query" value="">
            <input type="hidden" name="ac_index" value="">
            <input type="hidden" name="propertyId" value="">
            <input type="hidden" name="propertyIndex" value="">
            <input type="hidden" name="display" class="searchbox_form_type_display" value="for sale">
            <button class="btn btnPrimary submit"><span class="h5 typeEmphasize"><i class="iconSearch h4"></i>SEARCH</span></button>
          </span>
        </div>
      </form>
    </div>
    

    此外,如果您过滤页面发出的 GET 请求,您可以看到,当您在文本 bax 中插入一个值时,json 正在由 ajax 请求:

    {
        "locations": [{
            "value": "47977",
            "altValue": null,
            "display": "19901",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 0
        }, {
            "value": "47978",
            "altValue": null,
            "display": "19902",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 1
        }, {
            "value": "47979",
            "altValue": null,
            "display": "19903",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 2
        }, {
            "value": "47980",
            "altValue": null,
            "display": "19904",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 3
        }, {
            "value": "47981",
            "altValue": null,
            "display": "19905",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 4
        }],
        "suggestions": [],
        "success": true,
        "errors": []
    }
    

    这类似于我第一次给你的最后一个例子(使用 ajax 为你的搜索设置一个隐藏的 vaule 输入),然后在你的 php 文件中你可以切换到那个隐藏的输入值,在 json 中是 @987654327 @

    您可以使用这些附加信息再次阅读最后一个方法。

    如果我理解错了,请告诉我,希望对你有所帮助。


    如果您想为客户将搜索的每种搜索类型获取分隔列表,您可以输入另一个输入来引用搜索类型:

    <select name="field">
        <option value="zip">Zip Code</option>
    </select>
    <input type="text" name="keyword" />
    

    然后在你的 php 代码中:

    $field = $_REQUEST['field'];
    $keyword = $_REQUEST['keyword'];
    $query = "SELECT * FROM tbl_property";
    $where = "";
    switch ($field) {
        case 'zip':
            $where = " WHERE zip = " . $keyword;
            break;
        case 'addr':
            $where = " WHERE addr like " . $keyword . "%";
            break;
        case 'city':
            $where = " WHERE city like " . $keyword . "%";
            break;
    }
    $query = $query . $where . " GROUP BY zip LIMIT 0,5";
    

    这将为您提供一个单独的列表,具体取决于客户搜索的内容。

    其他形式是分析关键字中的数据,例如你知道如果你只有一个也可以转换为数字的单词,它指的是一个邮政编码

    您可以为此使用数组:

    $keyword = $_REQUEST['keyword'];
    $query = "SELECT * FROM tbl_property";
    $where = "";
    $parms = split(" ", $keyword);
    if(count($parms) == 1 && intval($parms[0], 10) > 0){
        $where = " WHERE zip = " . $keyword;
    }elseif (count($parms) > 1){
        $where = " WHERE addr like %" . $keyword . "%";
    }
    

    这取决于你自己的逻辑。

    如果我理解错了,请告诉我,希望对你有所帮助。


    MOD 03/05/2015 8:00:00 p.m.

    您还可以使用 javascript 和 ajax 获取您拥有的城市、邮政编码和地址列表,并在隐藏输入中设置您将进行的搜索类型。例如,使用 jQuery:

    <input type="text" name="keyword" id="keyword"           />
    <input type="hidden" name="field" id="field" value="all" />
    <div id="lists"></div>
    
    <script>
        $('#keyword').change(function() {
            $.ajax({
                type: "POST",
                url: "req.php",
                data:{ key: $(this).val() },
                success: function(data){
                    $('#lists').html(data);
                }
            });
        });
        $('#lists ul li').click(function(){
            $('#keyword').val($(this).html());
            $('#field').val($(this).parent().data('field'));
        });
    </script>
    

    关于 req.php

    $key = $_POST['key'];
    
    $db = new mysqli('localhost', 'user', 'pass', 'db');
    
    $query = "SELECT zip FROM tbl_property WHERE zip like " . $key . "%;";
    $zips = $db->query($query);
    
    $query = "SELECT addr FROM tbl_property WHERE addr like " . $key . "%;";
    $addrs = $db->query($query);
    
    echo ('<h1>Zips</h1><ul data-field="zip">');
    while($row = $zips->fetch_assoc()){
        echo ("<li>" . $row['zip'] . "</li>");
    }
    
    echo ('</ul><hr /><h1>Addrs:</h1><ul data-field="addr">');
    while($row = $addrs->fetch_assoc()){
        echo ("<li>" . $row['addr'] . "</li>");
    }
    echo ('</ul>');
    
    $db->close();
    

    如果我没有错过任何东西,它应该可以工作。

    如果我理解错了,请告诉我,希望对你有所帮助。

    【讨论】:

    • 非常感谢您的精彩解释,但恐怕它无法帮助我完成此搜索。我需要的是:如果您查看http://www.trulia.com 并搜索 zip,它只会获取 zip,如果用户输入街道号码:它只会获取所有街道号码(无 Zip,无地址)。如果用户输入地址也是一样,搜索只会找到匹配的地址(无邮编、无街道)。所以,首先只有一个输入字段没有下拉没有过滤器,我们需要过滤我的问题的数据库列。
    • 您能否访问http://www.trulia.com 并搜索您的家,靠近 zip,然后您会看到我需要什么。你的代码对我没有帮助。请帮助我度过难关。
    • 所以实际上您将最后一个示例引用到http://www.trulia.com 站点?我的意思是这会起作用吗?和以前一样,我试过了,但没有用。
    • 您能否在单独的问题中发布完整的工作示例?谢谢。
    【解决方案3】:

    你必须定义你的策略,你可以使用像 web www.trulia.com 这样的 JSON,或者 html 响应等等。

    你的html文件,使用json方式,记得定义自己的逻辑!:

    <input type="text" name="keyword" id="keyword" />
    <input type="hidden" name="field" id="field" value="all" />
    <div id="lists"></div>
    
    <script>
        $('#keyword').change(function() {
            $.ajax({
                type: "POST",
                url: "req.php",
                data:{ key: $(this).val() },
                success: function(data){
                    //Show the data to the clients
                    //(in a div or a "select2" plugin)
                    $.each(data.locations, function( key, value ) {
                        //iterate over locations
                    }
    
                    //SetUp hidden default value while keyword change
                    //Form the JSON Response
                    $('#field').val(data.locations[0].type); //Get the type of the first element in locations
                }
            });
        });
        $('#lists ul li').click(function(){
            $('#keyword').val($(this).html());
            $('#field').val($(this).parent().data('field'));
        });
    </script>
    

    req.php 文件:

    $key = $_POST['key'];
    
    $data = array(
                  'locations' => array(),
                  'errors'=>array(),
                  'success': true,
                  );
    
    header('Content-Type: application/json');
    
    $db = new mysqli('localhost', 'user', 'pass', 'db');
    
    if($db->connect_errno > 0){
        $data['errors'][] = $db->connect_error;
        die(json_encode($data));
    }
    
    $query = "SELECT zip FROM tbl_property WHERE zip like " . $key . "%;";
    if(!$zips = $db->query($sql)){
        $data['errors'][] = $db->connect_error;
        die(json_encode($data));
    }
    
    $query = "SELECT city FROM tbl_property WHERE city like " . $key . "%;";
    if(!$cities = $db->query($sql)){
        $data['errors'][] = $db->connect_error;
        die(json_encode($data));
    }
    
    $index = 0;
    
    while($row = $zips->fetch_assoc()){
        $data['locations'][] = array(
            "value": $row['zip'],
            "altValue": null,
            "display": $row['zip'],
            "type": "zipCode",
            "propertyIndex": "",
            "index": $index
        );
    
        $index = $index + 1
    }
    
    while($row = $cities->fetch_assoc()){
        $data['locations'][] = array(
            "value": $row['city'],
            "altValue": null,
            "display": $row['city'],
            "type": "city",
            "propertyIndex": "",
            "index": $index
        );
    
        $index = $index + 1
    }
    
    $db->close();
    
    header('Content-Type: application/json');
    echo json_encode($data);
    

    在 trulia.com 中的 JSON 响应:

    {
        "locations": [{
            "value": "47977",
            "altValue": null,
            "display": "19901",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 0
        }, {
            "value": "47978",
            "altValue": null,
            "display": "19902",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 1
        }, {
            "value": "47979",
            "altValue": null,
            "display": "19903",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 2
        }, {
            "value": "47980",
            "altValue": null,
            "display": "19904",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 3
        }, {
            "value": "47981",
            "altValue": null,
            "display": "19905",
            "type": "zipCode",
            "propertyIndex": "",
            "index": 4
        }],
        "success": true,
        "errors": []
    }
    

    在您的搜索 php 文件中(用户提交时将搜索的文件)

    $field = $_REQUEST['field'];
    $keyword = $_REQUEST['keyword'];
    $query = "SELECT * FROM tbl_property";
    $where = "";
    switch ($field) {
        case 'zip':
            $where = " WHERE zip = " . $keyword;
            break;
        case 'addr':
            $where = " WHERE addr like " . $keyword . "%";
            break;
        case 'city':
            $where = " WHERE city like " . $keyword . "%";
            break;
    }
    $query = $query . $where . " GROUP BY zip LIMIT 0,5";
    
    $db = new mysqli('localhost', 'user', 'pass', 'db');
    $result = $db->query($query);
    
    // show the result
    
    $db->close();
    

    如果我没有错过任何东西,它应该可以工作。

    如果我理解错了,请告诉我,希望对你有所帮助。

    【讨论】:

    • Matias:非常感谢您的帮助。但恐怕你的代码有很多 JSON 和数组语法错误。你能调查一下吗?此外,作为参考,请访问我遇到错误并想要实现它的这个 url。网址为:http://www.realtyexecutivesny.com/indextest.php
    • $('#field').val(data.locations[0].type); //Get the type of the first element in locations 行有 Uncaught SyntaxError: Unexpected identifier 错误。甚至我的 ajax 调用也没有通过。
    • 使用 JSON 会更好,因为我的情况会更快。因此,如果 JQuery 得到修复,使用 JSON 会更好。
    • 你的函数似乎对我不起作用,而且它也有错误。如果可以,请尝试更正代码,并始终确保仅发布工作代码以供将来使用。谢谢。
    • 对不起,我有很多工作,我会再次测试代码,因为我找不到错误。我会尽快回复
    猜你喜欢
    • 2016-09-22
    • 2022-10-24
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 2014-09-16
    相关资源
    最近更新 更多