简体   繁体   English

PHP:关键字搜索:查找字符串中的子字符串

[英]PHP: Keyword Searching: Find substring within a string

I am building a comics website and have implemented a search. 我正在建立一个漫画网站并实施了搜索。 The search originally used the image title... This worked fine: 搜索最初使用图像标题...这工作正常:

if (strtolower($input)==strtolower(substr($row['title'],0,strlen($input)))) {

But now I feel that many people won't remember the title. 但现在我觉得很多人都不会记得这个头衔。 So I've added a column to the database called "keywords", varchar [55]... and my test entry is the string "five, second, rule, food, rules". 所以我在数据库中添加了一个名为“keywords”的列,varchar [55] ...我的测试条目是字符串“five,second,rule,food,rules”。 I figured I could replace $row['title'] with $row['keywords'] and the search would still work. 我想我可以用$row['keywords']替换$row['title'] ,搜索仍然有用。

It worked if I start searching from the beginning of the string, like I enter "five, seco..." But not if I start from the middle of the string, like "second", or "rule", etc. 如果我从字符串的开头开始搜索就行了,比如我输入“five,seco ......”但是如果我从字符串的中间开始,如“second”或“rule”等,则不行。

Any ideas on how I can make that work? 关于如何使这项工作的任何想法?

Thanks! 谢谢!

Doing it in a comic's column will only bring tears as it breaks normalization. 在漫画专栏中这样做只会带来眼泪,因为它会破坏正常化。 What you should do is make a keyword table that has one word per entry and then a pivot table that matches keywords to comics. 你应该做的是创建一个关键字表,每个条目有一个单词,然后是一个与关键字匹配的数据透视表到漫画。 Then you can just do a join to find all the comics that match. 然后你可以只做一个连接来找到匹配的所有漫画。

It's more work to setup, but more flexible in the long run. 设置工作更多,但从长远来看更灵活。

EDIT: 编辑:

Keyword table: 关键字表:

id     keyword
1      x-men
2      action
3      mystery
4      batman
etc.

comic_keyword table comic_keyword表

comic_id    keyword_id
45          3
678         1
678         2
77          3
77          4
etc.

The second table (the pivot table) matches the ids of the comic to the ids of the keywords they're associated with. 第二个表(数据透视表)将漫画的ID与他们关联的关键字的ID相匹配。 That's how many-to-many relationships should be modeled in most cases. 这就是多数情况下应该建模的多对多关系。

The straightforward solution would be to use stripos instead: 直接的解决方案是使用stripos代替:

if(stripos($input, $row['title']) !== false) {
    // row matches
}

However, this isn't really a good solution. 但是,这不是一个很好的解决方案。 It would be much better to offload the filtering to your database, so non-matching rows don't have to make the trip to your front end at all. 将过滤卸载到数据库会更好,因此不匹配的行根本不需要前往您的前端。 If you keep keywords as a comma-separated field then LIKE or REGEXP would be a good choice of tool; 如果将关键字保留为以逗号分隔的字段,那么LIKEREGEXP将是一个很好的工具选择; if you normalized your database schema so that the 1-to-many relationship of comics to keywords is modeled with a separate comic_keywords table then matching would be even easier. 如果您规范化了数据库模式,以便将漫画与关键字的1对多关系建模为单独的comic_keywords表,那么匹配将更加容易。

For example, assuming that comic has an id and comic_keywords has a comic_id and a keyword , you could select matching comics with 例如,假设comic具有id并且comic_keywords具有comic_idkeyword ,则可以选择匹配的漫画

SELECT DISTINCT(comic_id) FROM comic_keywords WHERE keyword = 'blah'

You can split the column on the fly: 您可以动态拆分列:

if (in_array(strtolower($input), explode(', ', $row['title']))) {
  /* found it */
}

看起来你需要Sphinx或(不太可能,但更容易设置) MySQL的全文搜索

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM