【问题标题】:create LIKE friendly string from space separated sentence从空格分隔的句子创建 LIKE 友好字符串
【发布时间】:2014-08-04 18:31:54
【问题描述】:

我想让我的用户使用部分单词以任何顺序在数据库中搜索值,以便搜索到的字符串:

nan mu

将返回包含nanmu 的任何字符串,顺序不限。只有两位,使用array_filter()this 答案中的解决方案创建字符串相当容易

%nan%mu%
%mu%nan%

这样 mysql 将搜索那些。现在我有一个问题,当有两个以上的位时,例如nan mu te。目的是获取那些字符串:

$string1 = %nan%mu%te%
$string2 = %nan%te%mu%
$string3 = %mu%nan%te%
$string4 = %mu%te%nan%
$string5 = %te%nan%mu%
$string6 = %te%mu%nan%

并制作 6 个 mysql LIKE 条件 WHERE Field LIKE $string1 AND Field LIKE $string2 ... 以便结果中包含这三位任意顺序的任何可能性

对于那些即将抱怨 sql 注入的人,谢谢,但不,谢谢,我使用 PDO 和参数化查询。

我对字符串nan mu te的实际尝试:

class EstDefini
 {private $STR;
  function __construct($vSTR)
   {$this->STR = $vSTR;}
  function Verifier($vSTR)
    {return !($vSTR == $this->STR);}}

$vString = 'nan mu te';

$aBits = explode(' ',$vString);
$vNb = count($aBits);

for ($i=0;$i<$vNb;$i++)
 {$vAppend = implode('%',array_filter($aBits,array(new EstDefini($aBits[$i]),'Verifier')));
  $aLiterals[$i] = '%' . $aBits[$i] . '%' . $vAppend;}

只返回 3 个字符串,因为我的初始计数只有 3 个(我的分解字符串中有 3 个位):(这是var_dump($aLiterals)

array(3) {
  [0]=>
  string(10) "%nan%mu%te"
  [1]=>
  string(10) "%mu%nan%te"
  [2]=>
  string(10) "%te%nan%mu"
}

我最初的想法是修改计数:

$vNb = $vNb * max($vNb-1,1);

并尝试打乱其他位以获得不同的LIKE 友好字符串,但是由于我的初始$aBits 数组的大小仍然为3,因此此类创建调用new EstDefini($aBits[$i]) 将尝试访问未定义的位。

如何从空格分隔的单词中创建 LIKE 友好字符串,以便使用 MySQL 以任何顺序查找所有这些单词?

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    我认为这种方法有点错误 - 为什么你需要检查它是否是 field LIKE '%a%b%' OR field LIKE '%b%a%' 而你可以只检查它是否是 field LIKE '%a%' AND field LIKE '%b%' 并涵盖两者。

    $words = explode(' ', $string);
    $params = array_fill(0, count($words), '(?)');
    $search = implode(' AND field LIKE ', $params);
    $db->prepare("SELECT * FROM table WHERE field LIKE $search");
    
    $query->execute(array_map($words, function($word) { return '%' . $word . '%'; }));
    

    【讨论】:

    • +1 我只想评论过于复杂的检查。使用 lambda 函数的非常好的解决方案。
    【解决方案2】:

    将所述字符串分解成数组:

    $array = explode(" ", $string);
    

    之后,您可以为查询创建一个字符串,例如:

    $query = "SELECT * FROM table WHERE column LIKE (";
    

    然后像这样添加变量:

    $query .= "" . $array[0] . " OR "; //Or there for multiple strings.
    

    然后结束字符串队列:

    $query .= ")";
    

    可能不是最有效的方法,但可以完成工作。如果我需要详细说明,请发表评论。

    【讨论】:

    • 这行不通:我不希望返回只包含一个位的字符串,这就是 or 子句会发生的情况
    • 你对搜索长度有限制吗?
    猜你喜欢
    • 2021-05-06
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 2011-06-13
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多