PHP MYSQL搜索引擎 - 使用过滤器

时间:2013-09-10 20:37:26

标签: php mysql database search-engine

我正在开发一个带有大型数据库过滤器的PHP-MYSQL搜索引擎。 实际上搜索关键字工作正常,但我需要在查询中包含过滤器的输入,这是一个真正的问题。如果你能帮助我,我真的很感激,因为我不是专家。

以下是搜索:http://oi43.tinypic.com/wipr4l.jpg

引擎在名为“ reports ”的表格中搜索关键字。 “扇区”请求的数据由表*“sector_index_reports”提供* “country”请求的数据由表*“country_index_reports”*

提供

每个部门和国家/地区都有自己的ID。 例如:

  id       main_sec   main_reg
123234      23            218

这意味着报告 123234 是关于丹麦的摩托车( 23区)( 218区

报告链接到*“sector_index_reports”*和*“country_index_reports”* 通过身份证。

关系:http://oi39.tinypic.com/fa6igy.jpg

HTML:

<html>
      <div id="content">
        <p>Enter your search terms:</p>
        <form method="GET" action="<?php echo $_SERVER['PHP_SELF'];?>" name="searchForm">
          <p> Search For: <input type="text" name="keyword" value="" />
           <input type="submit" name="submit" value="Search!" />
           <label for="categories">Select category: </label>
           <select name="categories" id="categories">
             <option value="0">All sectors</option>
             <option value="1">Aerospace &amp; Transportation</option>
             <option value="2">Automotive</option>
             <option value="3">Banking, Finance &amp; Real Estate</option>
             <option value="4">Basic Materials</option>
             <option value="5">Business &amp; Government</option>
             <option value="6">Construction &amp; Heavy Industry</option>
             <option value="7">Consumer Goods &amp; Retail</option>
             <option value="8">Energy &amp; Utilities</option>
             <option value="9">Food &amp; Drink</option>
             <option value="10">Information Technology</option>
             <option value="11">Media &amp; Leisure</option>
             <option value="12">Pharma &amp; Healthcare</option>
             <option value="13">Telecomunication</option>
           </select>
           <label for="regions">Select Region:</label>
           <select name="regions" id="regions">
             <option value="0">All Regions</option>
             <option value="1">Africa</option>
             <option value="2">Asia</option>
             <option value="3">Australia and New Zealand</option>
             <option value="4">Central America</option>
             <option value="5"> Central and Eastern Europe</option>
             <option value="6">Central Asia</option>
             <option value="7">East Asia</option>
             <option value="8">Europe</option>
             <option value="9">Middle East</option>
             <option value="10">North Africa</option>
             <option value="11">North America</option>
             <option value="12">South America</option>
             <option value="13">South Asia</option>
             <option value="14">South East Asia</option>
             <option value="15">Western Europe</option>
           </select>
          </p>
        </form>

PHP

<?php

    $default_sort = 'ID';
    $allowed_order = array ('name','description');
    if (!isset ($_GET['order']) || 
        !in_array ($_GET['order'], $allowed_order)) {
        $order = $default_sort;
    } else {
        $order = $_GET['order'];
    }
// The following line stops the undefined index error on initial page load
    if (isset($_GET['keyword'])) {
            if(!$_GET['keyword']) {
              die('<p>Please enter a search term.</p>');
        }     
// Database Query Settings //
    $tables = 'reports' 'sector_index_reports' 'country_index_reports'; 
    $return_fields = 'name organizer_id no_pages publication_date price';
    $check_fields = 'name description';
// Get the keyword from the search form.
    $query_text = $_GET['keyword'];

// Sanitize Data Input
    $clean_query_text =cleanQuery($query_text);

// Call the bq_simple function and store the //
// resulting SQL Query in $newquery variable //
    $newquery=bq_simple ($return_fields, $tables, $check_fields, $clean_query_text);
    $newquery = $newquery . " ORDER BY $order;";

// sql data query construction //
    $result = mysql_query($newquery) or die(mysql_error());
/* make sure data was retrieved */
    $numrows = mysql_num_rows($result);
    if ($numrows == 0) {
        echo "<H4>No data to display!</H4>";
        exit;
    }
    echo    "<p>Your search '$query_text' returned ".$numrows. " results.</p>\n";
    echo    "<p>Click on the headings to sort.</p>\n";

/* now grab the first row and start the table */
    $row = mysql_fetch_assoc ($result);
    echo "<TABLE border=1>\n";
    echo "<TR>\n";
    foreach ($row as $heading=>$column) {
/* check if the heading is in our allowed_order
* array. If it is, hyperlink it so that we can
* order by this column */
        echo "<TD><b>";
        if (in_array ($heading, $allowed_order)) {
            echo "<a href=\"{$_SERVER['PHP_SELF']}?order=$heading&keyword=$query_text\">$heading</a>";
        } else {
            echo $heading;
        }                
        echo "</b></TD>\n";
    }
    echo "</TR>\n";
/* reset the $result set back to the first row and 
 * display the data */
    mysql_data_seek ($result, 0);
    while ($row = mysql_fetch_assoc ($result)) {
        echo "<TR>\n";
        foreach ($row as $column) {
            echo "<TD>$column</TD>\n";
        }
        echo "</TR>\n";
    }
    echo "</TABLE>\n";
    }

    function cleanQuery($string)
    {
      $string = trim($string);
      $string = strip_tags($string); // remove any html/javascript.
      if(get_magic_quotes_gpc())  // prevents duplicate backslashes
      {
        $string = stripslashes($string);
      }
      if (phpversion() >= '4.3.0')
      {
        $string = mysql_real_escape_string($string);
      }
      else
      {
        $string = mysql_escape_string($string);
      }
      return $string;
    }

# Internal function, used to support "+keyword -keyword" syntax in addition
#   to "and keyword not keyword" syntax.
function bq_handle_shorthand($text) {
    $text = preg_replace("/ \+/", " and ", $text);
    $text = preg_replace("/ -/", " not ", $text);
    return $text;
}

# Internal function, used to keep quoted text together when building
#  the query.  i.e.... [fish and chips and "chipped ham"] syntax
#
# It essentially replaces " " with "~~~~" as long as we aren't within
# a set of quotes, in which case " " is retained.  The string is then
# split on "~~~~~" with the surviving spaces intact.
function bq_explode_respect_quotes($line) {
        $quote_level = 0;   #keep track if we are in or out of quote-space
        $buffer = "";
        for ($a = 0; $a < strlen($line); $a++) {
                if ($line[$a] == "\"") {
                        $quote_level++;
                        if ($quote_level == 2) { $quote_level = 0; }
                }
                else {
                        if ($line[$a] == " " and $quote_level == 0) {
                                $buffer = $buffer . "~~~~";   #Hackish magic key
                        }
                        else {
                                $buffer = $buffer . $line[$a];
                        }
                }
        }
    $buffer = str_replace("\\", "", $buffer);
        $array = explode("~~~~", $buffer);
        return $array;
}

# Internal function, used to apply a single keyword against an
# arbitrary number of fields in the database in the same fashion.
#
# Works via replacing whitespace rather than interation
function bq_make_subquery($fields, $word, $mode) {
    if ($mode == "not") {
        $back = " LIKE '%$word%'))";
    }
    else {
        $back = " LIKE '%$word%')";
    }
    if ($mode == "not") {
        $front = "(NOT (";
        $glue = " LIKE '%$word%' AND ";
    }
    else {
        $front = "(";
        $glue = " LIKE '%$word%' AND ";
    }
    $text = str_replace(" ", $glue, $fields);
    $text = $front . $text . $back;
    return $text;
}
#
#  Generates the "WHERE" portion of a query, iterating over every keyphrase in the
#  given search string.  Is safe to link (e.g. with AND) with the output of repeated
#  calls
#
function bq_make_query($fields, $text) {
    #
    # We can't trust the user to give us a specific case
    #
    #$fields = strtolower($fields);
    $text = strtolower($text);
    #
    # Support +keyword -keyword
    #
    $text = bq_handle_shorthand($text);
    #
    # Split, but respect quotation
    #
    $wordarray = bq_explode_respect_quotes($text);
    $buffer = "";
    $output = "";
    #
    # work through each word (or "quoted phrase") in the text and build the
    #   outer shell of the query, filling the insides via bq_make_subquery
    #
    # "or" is assumed if neither "and" nor "not" is specified
    #
    for ($i = 0; $i<count($wordarray); $i++) {
        $word = $wordarray[$i];
        if ($word == "and" or $word == "not" and $i > 0) {
            if ($word == "not") {
                #
                # $i++ kicks us to the actual keyword that the 'not' is working against, etc
                #
                $i++;
                if ($i == 1) {   #invalid sql syntax to prefix the first check with and/or/not
                    $buffer = bq_make_subquery($fields, $wordarray[$i], "not");
                }
                else {
                    $buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "not");
                }
            }
            else {
                if ($word == "and") {
                    $i++;
                    if ($i == 1) {
                        $buffer = bq_make_subquery($fields, $wordarray[$i], "");
                    }
                    else {
                        $buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "");
                    }
                }
                else {
                    if ($word == "and") {
                        $i++;
                        if ($i == 1) {
                            $buffer = bq_make_subquery($fields, $wordarray[$i], "");
                        }
                        else {
                            $buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "");
                        }
                    }
                }
            }
        }
        else {
            if ($i == 0) {  # 0 instead of 1 here because there was no conditional word to skip and no $i++;
                $buffer = bq_make_subquery($fields, $wordarray[$i], "");
            }
            else {
                $buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "");
            }
        }
        $output = $output . $buffer;
    }
    return $output;
}

function bq_simple ($return_fields, $tables, $check_fields, $query_text) {
    #
    # Convert from space deliniated to comma deliniated for the query
    #
    $return_fields = str_replace(" ", ", ", $return_fields);
    $tables = str_replace(" ", ", ", $tables);
    #
    # build the query itself
    #
    $query = "SELECT $return_fields FROM $tables WHERE ";
    $query = $query . bq_make_query($check_fields, $query_text);
    #
    # Uncomment to debug
    #
    return $query;
}


?>

0 个答案:

没有答案