1

I have a project where I need some basic boolean search in pure PHP. It means I have plain strings I want to offer some simple boolean search on them. No database or other indexing engine is involved, so please don't refer to MySQL boolean search or lucene.

At the end something like the following code should print contains and not found.

$search = 'foo -bar "must have" -"must not have"';
$contentFound = 'This is some foo text you must have.';
$contentNotFound = 'This is some bar text you must have.';

if ($this->booleanSearch($contentFound, $search)) {
    echo 'contains';
} else {
    echo 'not found';
}
if ($this->booleanSearch($contentNotFound, $search)) {
    echo 'contains';
} else {
    echo 'not found';
}
Laoneo
  • 1,546
  • 1
  • 18
  • 25
  • Do you mean something like `strpos`? – ST2OD Apr 12 '16 at 06:47
  • No. This would not work as strpos looks only for the whole string and doesn't support boolean search. – Laoneo Apr 12 '16 at 06:50
  • What do you mean `boolean search`? Check if string contains `true`/`false`, or `1`/`0`? – Justinas Apr 12 '16 at 07:36
  • multiple strpos does support "boolean search" as well as regex does. What have you tried? – PeeHaa Apr 12 '16 at 07:53
  • just a hint: I would suggest to leave the "is there a library" question out of here, because you might get closed for requesting an off-site resource? You did describe the problem as the close-reason suggests, so I don't consider it offtopic, but someone might. – Nanne Apr 12 '16 at 07:54
  • @Nanne thanks for the hint. I'v removed the text. Hope it doesn't get closed. – Laoneo Apr 12 '16 at 08:24
  • @PeeHaa I did split the search string and made some regex out of it, to see if it matches, but forgot the phrase `"must have"` requirement. Now I wanted to get some input/recommendations of other developers. – Laoneo Apr 12 '16 at 08:28

1 Answers1

2

For a simple implementation you could just split the criteria (taking into account the quotes) and iterate over each criterion to see whether it matches or not:

function booleanSearch($content, $search) {
    $criteria = str_getcsv($search, ' ');

    while ($criteria) {
        $not = false;
        $q = array_shift($criteria);

        if (substr($q, 0, 2) === '-"') {
            $not = true;

            while (substr($q, -1) != '"') {
                $q .= " " . array_shift($criteria);
            }

            $q = substr($q, 2, -1);
        }
        else if (substr($q, 0, 1) === '-' && strpos($q, ' ') === false) {
            $not = true;
            $q = substr($q, 1);
        }

        $found = strpos($content, $q) !== false;

        if ($found === $not) {
            return false;
        }
    }

    return true;
}
Razvan
  • 2,436
  • 18
  • 23
  • It works, except for the search therm `$search = 'foo -"must have"';`, it splits must and have. – Laoneo Apr 12 '16 at 14:59
  • Yes, indeed, `-"must have"` was not present in your initial example and it was not dealt with in my code. Please see the updated version of the code. Also, you should note that there are some other edge cases as well (eg: `"-word"`) that you should take care of in your implementation (the snippet above should serve you just as a starting point). – Razvan Apr 13 '16 at 09:07
  • I'v used your script as starting point. I just added the comment, because I couldn't accept it like that as answer. – Laoneo Apr 13 '16 at 09:37