【问题标题】:PHP searching multiple database fields via separate form fieldsPHP 通过单独的表单字段搜索多个数据库字段
【发布时间】:2015-09-23 20:49:11
【问题描述】:

所以我有一个问题,一个非常基本但看起来很菜的问题!我从事 PHP 开发多年,知识进步似乎很慢。

我正在建立一个招聘网站,但在搜索职位空缺查询时遇到了问题。

我的表格是这样设置的..

<form class="form-search-list" action="search" method="get">
            <div class="row">
              <div class="col-sm-5 col-xs-6">
                <div class="form-group">
                  <label class="color-white">What</label>
                  <input type="hidden" name="type" value="basic">
                  <input class="form-control" name="keywords" style="text-transform: capitalize;">
                </div>
              </div>
              <div class="col-sm-5 col-xs-6">
                <div class="form-group">
                  <label class="color-white">Where</label>
                  <input class="form-control" name="location" style="text-transform: capitalize;">
                </div>
              </div>
              <div class="col-sm-2 col-xs-12">
                <div class="form-group">
                  <label class="hidden-xs">&nbsp;</label>
                  <button class="btn btn-block btn-theme  btn-success">Search</button>

                </div>
              </div>
            </div>
            <p class="text-right"><a href="#modal-advanced" data-toggle="modal" class="link-white">Advanced Search</a></p>
          </form>

如您所见,我正在使用$_GET[''] 从我选择的数据库表中获取数据,在本例中为vacancies

进入 search.php

    if(!isset($_GET['type'])){
    header("Location: jobsearch");
}

if($_GET['type']=='basic'){

        $keywords = $_GET['keywords'];
        $location = $_GET['location'];

$query = mysql_query("SELECT * FROM vacancies WHERE UNIX_TIMESTAMP() < `expires` AND jobtitle LIKE '%" .$keywords. "%' AND location LIKE '%" .$location. "%' AND active='1' ORDER BY id DESC");
$suffix = "SELECT COUNT(id) FROM vacancies WHERE UNIX_TIMESTAMP() < `expires` AND jobtitle LIKE '%" .$keywords. "%' AND location LIKE '%" .$location. "%' AND active='1'";  
$result = mysql_query($suffix) or die(mysql_error()); 
foreach(mysql_fetch_array($result) as $totjobs);
$suffixFT = ($totjobs != 1) ? 's' : '';

if(mysql_num_rows($query) == 0){
     $resultsterm = "Sorry, we couldn't find any job listings based on your search!"; 
    } else {
        if($_GET['keywords'] == "" AND $_GET['location'] == ""){
            $resultsterm = "We found <strong>" . mysql_num_rows($query) . "</strong> job listing" . $suffixFT . " throughout the UK.";
        } else {
            if($_GET['keywords'] == TRUE AND $_GET['location'] == ""){
                $resultsterm = "We found <strong>" . mysql_num_rows($query) . "</strong> job listing" . $suffixFT . " for <strong>$keywords</strong> throughout the UK.";
            } else {
                if($_GET['keywords'] == "" AND $_GET['location'] == TRUE){
                    $resultsterm = "We found <strong>" . mysql_num_rows($query) . "</strong> job listing" . $suffixFT . " in <strong>$location</strong>.";
                } else {
                    if($_GET['keywords'] == TRUE AND $_GET['location'] == TRUE){
                        $resulsterm = "We found <strong>" . mysql_num_rows($query) . "</strong> job listing" . $suffixFT . " for <strong>$keywords</strong> in <strong>$location</strong.";
                    }
                }
            }
        }
    }



}

我的数据库设置为(jobtitlelocation)我需要能够使用分解功能将我的搜索与这两个字段进行比较以搜索多个短语。..

例如,我的表中有一个名为“Test Vacancy”的空缺,当我搜索“Test”或“Vacancy' 它显示计数为 1,表示它找到了结果,但是如果我搜索 'Test Job' 它不会显示结果!

这真的让我很困惑。我花了整整 8 个小时试图弄清楚这一点,但我无法理解它!

我试图弄清楚我们如何在$keywords$location 中使用explode 函数我知道如何使用explode 函数并将它放入只有一个变量但没有得到的foreach 循环中尝试使用这两个变量时从哪里开始的线索。

如果你们中的一个可爱的人能帮助我,让我知道该怎么做,那将不胜感激。

更新

我已经构建了以下代码块,哪种工作..

$keywords = $_GET['keywords'];
$jobkeywords = explode(' ',$keywords);

$location = $_GET['location'];
$lockeywords = explode(' ',$location);

$searchColumns1 = array("jobtitle");
$searchCondition1 = '';
$searchColumns2 = array("location");
$searchCondition2 = '';
  for($i = 0; $i < count($searchColumns1); $i++)
    {
        $searchFieldName1 = $searchColumns1[$i];
        $searchCondition1 .= "$searchFieldName1 LIKE '%" . implode("%' OR $searchFieldName1 LIKE '%", $jobkeywords) . "%'";
        if($i+1 < count($searchColumns1)) $searchCondition1 .= " OR ";
     }
    for($i = 0; $i < count($searchColumns2); $i++)
    {
        $searchFieldName2 = $searchColumns2[$i];
        $searchCondition2 .= "$searchFieldName2 LIKE '%" . implode("%' OR $searchFieldName2 LIKE '%", $lockeywords) . "%'";
        if($i+1 < count($searchColumns2)) $searchCondition2 .= " OR ";
     }

$query = mysql_query("SELECT * FROM vacancies WHERE $searchCondition1 AND $searchCondition2");
$suffix = "SELECT COUNT(id) FROM vacancies WHERE $searchCondition1 AND $searchCondition2";  

但是在检查和从表中获取方面不是很严格.. 例如,如果我有一份工作,例如名称“测试空缺”,其位置是“英国伦敦”,但我在“英国伦敦”中搜索“其他工作”,它仍然显示结果,即“ “测试空缺”,因为它位于伦敦!我不希望它这样做,相反,如果职位名称不匹配,那么它将显示“未找到结果”,就好像它正在单独使用位置字段,而不是关键字和位置一起工作以检查是否存在是匹配的。

有什么想法吗?

进一步更新

感谢您的投入和帮助 LinesofCode,感谢您为帮助我分配所做的努力!

让我们看看我是否可以更清楚地了解我想要实现的目标,我之前的问题在阅读后似乎有点模糊和离题。

我的表单上有两个字段,第一个是关键字..第二个是位置.. 因此用户将在关键字框中输入“测试空缺”,然后输入他们想要的位置。在我的空缺数据库表中它包括与表单中的关键字进行比较的职位,然后是我在他们的测试空缺的位置字段,如下所示jobtitle='Test Vacancy'location ='Southport Merseyside United Kingdom' 所以理想情况下,我想做的是使用职位名称的分解功能(表格上的关键字)将'Test'或'Vacancy'与位于'Southport Merseyside United Kingdom'的工作相匹配,现在对于用户可以输入他们喜欢的任何内容的位置.. 我无法控制,他们可以在“Southport United Kingdom”中搜索“Test Job”,所以我需要脚本通过使用来获取“Test Vacancy”爆炸功能以匹配单词“测试”,但同时对搜索位置非常严格。我从经验中知道,在关键字和位置上使用爆炸功能会导致分配不需要的数据,用户可以在“伦敦”中搜索“管理员”,而不是只显示伦敦的管理员职位,而是显示所有列表在伦敦。

我需要编写一个相当混乱和复杂的脚本,我只是不知道从哪里开始!

进一步更新

@Linesofcode 这个块似乎实现了我想要的,但是有一个小问题.. 请看块然后我会解释问题

$keywords = explode(" ", $_GET['keywords']);
$location = explode(" ", $_GET['location']);

if (!empty($keywords) && count($keywords) > 0) {

    $query = "SELECT COUNT(id) FROM vacancies WHERE";

foreach($keywords as $keyword) {
    $keyword = mysql_real_escape_string($keyword);
    $query .= " jobtitle LIKE '%{$keyword}%' OR";
}

foreach($location as $loc) {
    $loc = mysql_real_escape_string($loc);
    $query .= " location LIKE '%{$loc}%' OR";
}

$query = rtrim($query, 'OR');

    }

$result = mysql_query($query) or die(mysql_error());
foreach (mysql_fetch_array($result) as $totrows);

echo $query;

这个块会输出

SELECT COUNT(`id`) FROM vacancies WHERE jobtitle LIKE '%test%' OR jobtitle LIKE '%vacancy%' **OR** location LIKE '%southport%' OR location LIKE '%pr9%' OR location LIKE '%0tl%'

正如您在 sql 输出中看到的那样,我将 OR 语句加粗,需要将其更改为 AND 看起来像这样

SELECT COUNT(`id`) FROM vacancies WHERE jobtitle LIKE '%test%' OR jobtitle LIKE '%vacancy%' **AND** location LIKE '%southport%' **OR** location LIKE '%pr9%' OR location LIKE '%0tl%'

我构建的块可以吗?

进一步更新

所以构造块的工作原理..

$keywords = explode(" ", $_GET['keywords']); $location = explode(" ", $_GET['location']);

if (!empty($keywords)) {        $query = "SELECT * FROM vacancies WHERE";

foreach($keywords as $keyword) {
    $keyword = mysql_real_escape_string($keyword);
    $query .= " jobtitle LIKE '%{$keyword}%' OR"; }

$query = preg_replace('/OR$/', 'AND', $query);

foreach($location as $loc) {
    $loc = mysql_real_escape_string($loc);
    $query .= " location LIKE '%{$loc}%' OR"; }

$query = rtrim($query, 'OR');

echo $query;

echo "<p></p>";

$result = mysql_query($query) or die(mysql_error()); while ($row = mysql_fetch_assoc($result)){     echo "" . $row['jobtitle'] . ""; }

    }

但是,当我认为我的 foreach 循环混淆了我的 while 循环以显示来自数据库的结果时..

我在“London”中搜索“Test Vacancy”(我的数据库中的实际位置是“Southport”,但它仍然显示,但是当我只搜索“Test in London”时,它不会显示应该执行的操作, 好像当输入两个关键字时它正在播放,但是当只输入一个时它可以正常工作.. 有什么想法吗?那个代码看起来好吗?

【问题讨论】:

  • 您容易受到sql injection attacks 的攻击。而你的select count() 毫无意义。您正在运行另一个查询以获取与您可以从 mysql_num_rows($query) 获得的完全相同的数据。
  • 您需要将最后一个OR 替换为AND。在keywords loop 之后,您可能需要添加$query = preg_replace('/OR$/', 'AND', $query);
  • 它可以工作@Linesofcode!你对我帮助很大 :) 如果你有贝宝账户,我想捐赠一些东西作为感谢
  • 大声笑,不,谢谢。我不帮助人们以获得任何形式的奖励。祝你好运。
  • @Linesofcode 嗯,我很感激!谢谢分配。我还有一个问题!我不确定它是否是我的 while 循环来显示我的数据库中的结果,我觉得我的 foreach 循环让我的 while 循环感到困惑。如果您愿意提供帮助,请参阅我的更新问题以获取更多详细信息或提供一些意见

标签: php mysql search foreach explode


【解决方案1】:

LIKE '%Test Job%'Test Job 视为单个实心字符串。 MySQL 不会单独考虑每个单词。如果您想考虑个人工作,那么您必须将条件写为

(foo LIKE '%Test%') OR (foo LIKE '%Job%')

注意%...% 匹配效率非常低,不能使用任何索引。如果您确实想使用搜索词组查找单个词,请考虑改用 FULLTEXT 搜索。

【讨论】:

    【解决方案2】:

    首先,locations 我相信是一个固定值,如果是这样就更容易了。请注意,这只是一个算法示例。

    $keywords        = 'Test Vacancy';
    $locations       = 'London, Manchester, Liverpool';
    
    $listOfKeywords  = explode(' ', $keywords);
    $listOfResults   = array();
    
    foreach($listOfKeywords as $keyword)
    {
       /*
        * This should reproduce something like:
        *  
        * SELECT * FROM vacancies WHERE jobtitle LIKE %Test% AND location IN(London, Manchester, Liverpool)
        * SELECT * FROM vacancies WHERE jobtitle LIKE %Vacancy% AND location IN(London, Manchester, Liverpool)
        *
        */
       $strQuery = "SELECT * FROM vacancies WHERE jobtitle LIKE '%" . $keyword . "' AND location IN(" . $locations . ")";
    
       $query    = mysqli_query($yourConnection, $strQuery);
    
       while($row = mysqli_fetch_array($query))
       {
          $listOfResults[] = array('id'        => $row['id'], 
                                   'jobtitle'  => $row['jobtitle']);
       }
    }
    
    if(count($listOfResults) == 0)
       echo 'Nothing found..'
    else
       echo 'We found ' . count($listOfResults) . ' results';
    

    【讨论】:

    • 我添加了一个新块,请看更新后的代码!关于我能做什么的任何想法?
    • 我认为您不必要地创建了令人困惑的代码。我已经更新了我的答案,以便您可以更好地预览。你试过了吗?
    • 我已经尝试了您的代码,并收到以下错误通知:第 12 行的 C:\xampp\htdocs\jobsite\query.php 中的数组到字符串转换我两次收到该错误,所以它来了来自 $query
    • 好吧,正如我所说的,这只是一个算法示例,您需要了解它并以自己的方式实现。但那个错误是我的错,不是你的。查看更新的答案。
    • 它没有显示任何结果。无论如何,谢谢你的努力:)我真的很感激!我会研究它,看看我能把什么放在一起
    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 2015-09-07
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多