I’m building a very simple profanity filter in a chat app. I know they are notoriously difficult to implement properly, but I just want something quick and simple that is better than nothing at all.
I have a profanities table structured as follows:
|----|-----------|
| ID | Word |
|----|-----------|
| 01 | Banana |
| 02 | Melon |
| 03 | Eggplant |
| 04 | Pineapple |
|----|-----------|
My basic query to find if a word a user has typed appears on the profanities table is pretty simple:
SELECT ID FROM profanities WHERE Word = '$word';
I can modify this to use LIKE
or % etc., but that’s pretty straightforward.
What I also want is to combine this with a query that also checks if a word on the table is WITHIN the word the user typed. For example, the above query fails on words like "AllBananas" or even BananaMelon. I have tried some combinations of LOCATE()
but they don’t work.
Is there a way to combine a query that checks if a passed word (or similar) is both ON the table, as well as if any word on the table appears WITHIN the passed word?
2
Answers
When you switch positions it will work
You would also need a collation that is case insensitive
Your code suggest that you don’t use prepared statements, that can lead to sql injection and cause problem, so it would be better to switch to prepared statements all the time.
fiddle
You can get both tests in the same query – do two LOCATE() tests in Case expressions
Additionaly – if you want to know if there is a match anywhere you can enclose Case expressions within GREATEST() function and get the results as below: