Cory Dobson
Cory Dobson

Reputation: 73

Check if string contains all values in array with php

What I have so far:

$searchQuery = "keyword1 keyword2";
$searchArray = explode(" ", $searchQuery);
$stringToCheck = "keyword1 keyword3 keyword2";
foreach ($searchArray as $searchKeyword) {
    if (strpos($stringToCheck, $searchKeyword) !== false) : 
    //do something
    endif;
}
endif;

What I want is to display something only if ALL values in the search query are found in a string. With my current code above, if the string contains keyword1 and keyword2, it "does something" twice, once for each match. It also comes up as true if the string only contains keyword1 but not keyword2, in that case it displays the content once.

Upvotes: 2

Views: 2606

Answers (3)

Undiscouraged
Undiscouraged

Reputation: 1125

If you prefer array_reduce over foreach this might be an option for you:

$search = ['keyword1', 'keyword2'];
$keywords = ['keyword1', 'keyword3', 'keyword2'];
$allPresent = array_reduce(
    $search,
    static fn (bool $carry, string $s) => $carry && in_array($s, $keywords, true),
    true
);

if ($allPresent) {
    /* Do something. */
}

Though, it does not bail out early in case of false - that is in contrast to the answer from @George Bahij.

Upvotes: 0

Oluwaseyitan Baderinwa
Oluwaseyitan Baderinwa

Reputation: 1137

For anyone who might need another way. I came up with this while looking for a solution. Ensure what's to be tested are both arrays;

$var1 = explode(' ',"a string to be turned to an array");
$var2 = ["test","a","string","array"];

Get the counts (or lengths) of both arrays;

$var1count = count($var1);
$var2count = count($var2);

//Get the intersection of both arrays with array_intersect() method

$intersect = array_intersect($var1,$var2);

//check if the count (or length) of the intersect is the same as the test var (eg $var1)

if(count($intersect)===$var1count)//it has all the words

FYI: case sensitive. You might want to convert all to lower or upper case

Upvotes: 0

George Bahij
George Bahij

Reputation: 627

Solution

function str_contains_all($haystack, array $needles) {
    foreach ($needles as $needle) {
        if (strpos($haystack, $needle) === false) {
            return false;
        }
    }
    return true;
}

Usage:

$haystack = 'foo, bar, baz';
$needles = array('foo', 'bar', 'baz');

if (str_contains_all($haystack, $needles)) {
    echo "Success\n";
    // ...
}

Notes

Since you specified that you only wish to perform an action when the "haystack" string contains all the substring "needles", it is safe to return false as soon as you discover a needle that is not in the haystack.

Other

Using if (...): /* ... */ endif; is fairly uncommon in PHP from my experience. I think most developers would prefer the C-style if (...) { /* ... */ } syntax.

Upvotes: 5

Related Questions