Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 其中x类似“%$find%”-如果$find=2个独立的值会怎么样?_Php_Mysql_Forms_Search - Fatal编程技术网

Php 其中x类似“%$find%”-如果$find=2个独立的值会怎么样?

Php 其中x类似“%$find%”-如果$find=2个独立的值会怎么样?,php,mysql,forms,search,Php,Mysql,Forms,Search,我正在为产品目录创建搜索功能 以下是迄今为止的输入代码: <form name="search" method="post" action="'.$PHP_SELF.'"> <div> Search for: <input type="text" name="find" /> <input type="hidden" name="searching" value="yes" /> <input type="su

我正在为产品目录创建搜索功能

以下是迄今为止的输入代码:

<form name="search" method="post" action="'.$PHP_SELF.'">
    <div>
    Search for: <input type="text" name="find" />
    <input type="hidden" name="searching" value="yes" />
    <input type="submit" name="search" value="Search" />
    </div>
</form>
当用户搜索一个单词字符串时,这一切都非常好

这里的问题是,当用户搜索两个单词的字符串时,找不到匹配项,因为有时这些字符串与单独的功能相关

例如,产品目录包含各种巧克力的信息:

你会得到一条条的巧克力、一盒盒的巧克力、一包包的巧克力等等

现在,尽管desc字段中的一些描述包含单词chocolate和bar,但有些描述包含变体,比如company bars 120g chocolate

这会导致上述代码出现问题,因为如果用户搜索巧克力,除非desc字段中的描述明确包含该变量,则不会返回匹配项

我希望发生的是,当用户搜索巧克力棒时,包含巧克力棒和巧克力棒的任何匹配项都将被返回

有人对我将如何完成这项任务有任何意见吗


是否可能将$find转换为数组并生成分隔符?

您需要将字符串拆分为多个部分,然后将它们分别添加到where子句中。即:

.... WHERE `desc` LIKE '%bar%' OR `desc` LIKE '%chocolate%'
但请注意,这可能是一个有点慢的查询!无论如何,SQL中的通配符搜索速度很慢,多个通配符会使问题更加复杂

使用全文,您可能会更快地获得结果。这需要额外的数据库设置工作,但更重要的是,它在您给出的示例中可能没有用处,因为全文通常会从索引中删除短单词。它是可配置的,所以您可能可以让它工作,但全文的重点是为大块文本建立搜索索引;它实际上并不适用于较短的字符串

这类问题更常见的解决方案是使用标记,搜索标记而不是字符串。这基本上需要一个单独的表,其中包含每个记录中的所有相关关键字,并单独存储。这允许您进行非常快速的搜索,因为您可以完全消除通配符。您甚至可以添加可能不在实际文本中的其他同义词关键字,这有助于使搜索更易于使用


如果您的用户确实无法通过标记解决方案找到他们想要的内容,您仍然可以为他们提供高级搜索,这可以回到通配符解决方案。只需确保他们知道它会很慢。

您应该查看全文索引

描述类“%word%” 会越来越重。 用户还可以提供2个单词甚至更多。只需将查询分解为更多单词,并构建一个where子句,涵盖所有可能性:

WHERE desc LIKE '%word1%' or desc LIKE '%word2%' OR  ....

同样,这不是很有效或快速,全文+匹配效果更好。

也许你可以这样做:

$keywords_array = explode(' ', $find);

$qry = "SELECT * FROM `products` WHERE `desc` LIKE '%" 
       . implode("%' OR `desc` LIKE '%", $keywords_array) 
       . "%'";
$find='this'的输出:

从描述如“%this%”的产品中选择*

$find的输出='this and that':

从描述类“%this%”或描述类“%and%”或描述类“%that%”的产品中选择*


这当然是一个非常基本的功能,但是你知道了。

漂移到regexp怎么样

您可以将空格替换为| in$find或您喜欢模拟的任何输入语法OK:

巧克力棒=>chocolate | bar甚至\b巧克力棒\b如果您需要单词边界

或者,您可以转换为以下方式进行模拟和

巧克力棒=>巧克力棒。*巧克力棒

然后执行:

其中desc REGEXP“$find”


仔细检查性能是否适合您。

第一个问题是将搜索拆分为单个单词。这可以在PHP中轻松完成,但根据您的搜索,您可能还启用了短语,例如,这是一个短语 如果没有,只需按空格分割搜索文本就很容易了

对于第二个问题,两种可能的解决方案都已发布,您可以使用。。。比如“巧克力%”或者“巧克力条%”注意:我只在单词后面加了%——我会避免在两边都用它,除非你也想找到单词部分,例如hocol必须仍然匹配chocolade。这是非常缓慢的,因为索引无法使用


如前所述,更好的解决方案是使用匹配。。。反对,因为此解决方案使用全文索引,大大加快了搜索速度

这就是类别/标签的用途。@Tomalak你好!我对此很陌生,但我会研究这些类别和标签,谢谢你的输入!我的意思是,你可以创建它们,索引它们,然后搜索它们,而不是强迫自己通过人类可读的描述来搜索,而这并不能完成整个词的搜索。我更喜欢从输入标记构建一个聪明的全文搜索。desc是一个保留字,请把它放在后面的勾号中。这就是我一直以来的想法。但事实上你是
我没说一点。关于更快的方法有什么建议吗?@cularis-当然有。固定的为了我自己的利益,打字太快了:-@BlackberryFan-添加了一些关于其他解决方案的注释。
$keywords_array = explode(' ', $find);

$qry = "SELECT * FROM `products` WHERE `desc` LIKE '%" 
       . implode("%' OR `desc` LIKE '%", $keywords_array) 
       . "%'";