我想允许我的用户使用任何顺序的部分单词搜索数据库中的值,以便搜索到这个字符串:
nan mu
将以任何顺序返回包含nan
和mu
的任何字符串。只有两位,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个字符串,因为我的初始计数只有三个(我的爆炸字符串有三位):(这是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查找任何顺序的所有单词?
答案 0 :(得分:6)
我认为这种方法有点不对 - 为什么你需要检查它是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 :(得分:0)
将所述字符串分解为数组:
$array = explode(" ", $string);
之后,您可以为查询创建一个字符串,如:
$query = "SELECT * FROM table WHERE column LIKE (";
然后像这样添加变量:
$query .= "" . $array[0] . " OR "; //Or there for multiple strings.
然后用:
结束字符串队列$query .= ")";
可能不是最有效的方法,但可以完成工作。如果我需要详细说明请发表评论。