【问题标题】:PHP: Coding "advanced search" the best wayPHP:编码“高级搜索”的最佳方式
【发布时间】:2010-10-02 13:37:24
【问题描述】:

好的,我想要一些关于如何以正确的方式编写高级搜索配置文件的建议。

“高级”搜索包含:

Gender   female/both/male
Search in    All/latest profiles 1/2/7/14/32 days ago
Online: Yes(checked)
Age (xx) to (xx) years (xx means you can write e.g 12 and 18)
Cities: all/city1/city2/city3

您可以选择很多标准。

我想知道我应该如何以最有效的方式编写代码,并且代码重复最少。我应该根据用户选择的内容构建查询吗?示例:

$query = "SELECT * FROM users WHERE"
if(!empty($gender){ // if its empty, then the user chose both..
    $query .= "gender = $gender";
}
....

或者有没有更好的解决方案?我认为这样做会导致问题,因为如果用户没有选择任何性别,而另一个如果 $online (example) 以 AND 开头,则会导致 WHERE AND ..

【问题讨论】:

    标签: php search


    【解决方案1】:

    我认为您的解决方案是一个好的开始。继续检查您的高级搜索字段并根据需要构建 SQL where 子句。

    如果您需要进行模糊逻辑 - Males OR City1,就会出现问题。但你没有在你的 OP 中指出这一点。

    要避免WHERE AND,只需使用真正的表达式开始您的 where 子句:

    $query = "SELECT * FROM users WHERE 1"
    

    这将始终评估为真,当您添加更多条件时,它们将正确附加 - SELECT * FROM users WHERE 1 AND city = 'city1'

    【讨论】:

      【解决方案2】:

      “与”问题很容易解决:

      $andArr[] = "gender = $gender";
      $andArr[] = "age between $from and $to";
      ...
      
      $adsString = implode(' AND ', $andArr);
      

      对于性别,我会使用预先选择“两者”的下拉菜单。

      【讨论】:

      • 请不要使用未初始化的变量,如andArr。此外,我很高兴在最后一行 $andArr 之后不应该有任何大括号。已编辑。
      • 这只是一个代码 sn-p。通常我初始化我所有的变量。 $andArr = 数组();将在我的 $andArr[] = ...; 之前
      • 内爆是做什么的?如果我回显字符串,它会是性别 = $gender AND $from 和 $to 之间的年龄吗?
      • 它接受一个数组并将其与粘合字符串粘合。所以它将“AND”放在每个数组字段之间,并将它们放在一个字符串中。
      【解决方案3】:

      请不要编写允许SQL injections 的代码。另外,请确保您的 php 代码使用register_globals set to off 运行。除此之外,我认为它没有任何理由不能那样工作。

      所以这里是一个简单的例子,使用PDO

      $query = 'SELECT * FROM users WHERE 1';
      $params = array();
      if (!empty($_POST['gender'])) {
          $query .= ' AND gender=:gender'
          $params[':gender'] = $_POST['gender'];
      }
      ...
      $st = $pdo->prepare($query);
      $result = $st>execute($params);
      

      【讨论】:

      • 如果我在上面的示例中只在 $query 开头添加“WHERE 1”,它是否允许 sql 注入?
      • @user457827 我只是假设 $gender 将是用户的直接输入(这需要 register_globals)。如果您无论如何都进行了一些预处理,那么如果预处理是正确的,那么它是安全的。基本上,确保它的唯一方法是使用安全函数,例如 intval 或检查它与可能值的硬编码列表。由于那里很容易搞砸,我会一直使用准备好的语句。
      • 准备好的语句,它是如何工作的?我对此很陌生。上面的例子看起来很高级,你使用 PDO,所以,$result 是否像正常工作一样(所以你可以做 $mysql_num_rows($result) 和 fetch_array($result) ?)
      • 准备好的语句和/或输入验证和/或输入转换方法,如 mysql_escape_string
      • 如果我将上面的示例与 WHERE 1 一起使用并将所有输入设为 mysql_escape_string,我会不会没事。有什么可能让它变得脆弱。到sql注入
      猜你喜欢
      • 2010-10-12
      • 2023-04-01
      • 1970-01-01
      • 2015-07-13
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 2013-08-07
      • 2016-09-06
      相关资源
      最近更新 更多