帮助在PHP中设置高级搜索参数的逻辑

时间:2011-03-19 00:13:28

标签: php oop model-view-controller search codeigniter

我想创建一个高级搜索表单,就像工作网站会有一个包含关键字,工作类型,最低工资,最高工资,类别,子类别等标准的搜索表单...

我的问题是决定如何最好地设置它,所以如果我必须在参数中添加类别,我不需要修改一大堆查询和函数等......

我最好的猜测是从所有潜在的参数中创建某种关联数组并重用这个数组但是出于某种原因我觉得它比这复杂得多。我使用CodeIgniter作为MVC框架,如果这有任何区别。

有人建议如何最好地设置它吗?

请记住,我需要生成链接,例如index.php?keyword = designer& job_type = 2& min_pay = 20& max_pay = 30

我希望我的问题不是模糊。

9 个答案:

答案 0 :(得分:2)

我不知道这是否是你需要的,但我通常会创建一些搜索类。

<?php
$search = new Search('people');
$search->minPay(1000);
$search->maxPay(4000);
$search->jobType('IT');
$results = $search->execute();

foreach ($results as $result)
{
  //whatever you want
}

?>

您可以拥有所有这些方法,或者在方法名称和数据库字段之间的__set()处进行一些映射。传递给构造函数的参数是执行主查询的表。在__set()中的方法或映射中,您必须处理任何所需的连接以及要加入的字段。

答案 1 :(得分:1)

有更多“企业级”方法可以做到这一点,但对于小型网站来说,这应该没问题。您可以根据需要使用lots more ActiveRecord methods。 CI将链接它们以便您发出有效的SQL请求。

if($this->input->get('min_pay')) {
  $this->db->where('min_pay <', $this->input->get('min_pay'));
}

if($this->input->get('keyword')) {
  $this->db->like($this->input->get('keyword'));
}

$query = $this->db->get('table_name');
foreach ($query->result() as $row) {
  echo $row->title;
}

答案 2 :(得分:1)

要以一种很好的方式使用搜索标准,您应该使用类和接口。

比方说,您可以定义一个 ICriteria接口。然后你有Criteria,TimeCriteria,DateCriteria,listCriteria,TextSearch Criteria,IntRange Criteria等不同的子类型(实现)。

您的标准界面应提供的是每个标准的一些getter和setter,您必须为每个标准处理3次使用:

  • 如何显示他们
  • 如何使用结果填充查询
  • 如何保存他们(在会话或数据库中)供以后使用

显示标准时,您需要:

  • 标签
  • 可用运算符列表(in,not in,=,&gt;,&gt; =,&lt;,&lt; =,包含,不包含) - 并且每个子类型都可以决定该列表的哪一部分已实施
  • 条目区域(列表,文本输入,日期输入等)

您的主要代码只会处理ICriteria元素,要求他们自己构建,显示它们,给它们用户输入,要求它们保存或循环它们以根据它们的当前值在SQL查询上添加SQL条件。 一些Criteria实现将继承其他实现,一些将只需要定义可用的运算符列表,一些将扩展简单的行为以添加丰富的UI(假设一些Date元素应该提供类似'在最后一天'的列表,'在上周','去年','自定义范围')。

将SQL查询作为对象处理,而不仅仅是字符串,例如Zend_Db_Select的工作方式,这是一个非常好的主意。由于每个Criteria都会在最终查询中添加自己的部分,其中一些可能会添加leftJoins或复杂的查询部分。

答案 3 :(得分:0)

搜索查询有时会很痛苦,但不会像分页那样痛苦。幸运的是,CodeIgniter可以通过它们的分页库帮助您解决这个问题。

我认为你走在正确的轨道上。我想说的基本要点是:

  1. 从网址抓取您的GET变量。
  2. 创建数据库查询(清理GET值)。
  3. 生成结果集。
  4. 做分页。
  5. 现在,CodeIgniter默认会破坏GET变量,因此请确保在配置文件中启用http查询字符串。

    祝你好运!

答案 4 :(得分:0)

我对CodeIgniter一无所知,但对于我曾经支持的搜索应用程序,我们有下拉组合框,其中类别选项存储在数据库表中,并依赖应用程序和数据库缓存来避免每次页面显示时都会跳闸(这是学习的机会;-)。更新job_type,location等表时,新值将显示在组合框中。

取决于

  • 您打算有多少类别下拉列表
  • 您预计必须更新列表的频率
  • 你需要它有多动态。

  • 您的网站规模和整体活动是您必须考虑的因素。

我希望这会有所帮助。

P.S。因为您似乎是新用户,如果您得到的答案可以帮助您,请记住将其标记为已接受,或者给它一个+(或 - )作为有用的答案

答案 5 :(得分:0)

分页课是一个很好的基础。首先收集查询字符串变量。

<?php

    // ...in Pagination class

    $acceptableVars = array('page', 'delete', 'edit', 'sessionId', 'next', 'etc.');

    foreach($_GET as $key => $value) {
        if(in_array($key, $acceptableVar)) {
            $queryStringVars[] = $key . '=' . $value;
        }
    }

    $queryString = '?' . implode('&', $queryStringVars);

    $this->nextLink = $_SEVER['filename'] . $queryString;

    ?>

答案 6 :(得分:0)

将可搜索信息复制到另一个表中。将数据集转换为具有两个值的列,例如:搜索颜色=白色或红色可以成为对表中10列的搜索,每个列包含一个值为1或0的颜色。结果可以在您获得计数器后进行分组对于每个搜索过滤器。 将文本转换为全文搜索,并在此搜索表上使用MATCH和许多索引。最终将文本列组合成一个可搜索列。搜索的结果将是ID,然后您可以将其转换为SQL

中具有IN()条件的记录

答案 7 :(得分:0)

Agile Toolkit允许以下列方式添加过滤器(只是为了与CodeIgniter进行并排比较,也许你可以采取一些概念):

$g=$this->add('Grid');
$g->addColumn('text','name');
$g->addColumn('text','surname');
$g->setSource('user');

$conditions=array_intersect($_GET, array_flip(
  array('keyword','job_type','min_pay'));

$g->dq->where($conditions);

$ g-&gt; dq是一个动态查询,其中()转义从$ _GET传递的值,因此可以安全使用。其余的,分页,列显示,与MVC的连接取决于框架。

答案 8 :(得分:0)

    function maybeQuote($v){
        return is_numeric($v) ?: "'$v'";
    }

    function makePair($kv){
    +--  7 lines: $a = explode('=', $kv);
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    }

    function makeSql($get_string, $table){
    +-- 10 lines: $data = explode('&', $get_string);
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    }
    $test = 'lloyd=alive&age=40&weather=hot';
    $table = 'foo';
    print_r(makeSql($test, $table));