Str::contains

Determines whether a string contains a given value, or any value from an array.

Signature
Str::contains(string $haystack, string|iterable<string> $needles, bool $ignoreCase = false): bool

Parameters

ParameterTypeDescription
$$haystackstringThe string to search inside.
$$needlesstring|iterable<string>A single value, or any iterable of values. The method returns true as soon as one of them is found.
$$ignoreCaseoptionalbool= falseWhen true, both haystack and needles are lower-cased with mb_strtolower() before comparison.

Return value

booltrue if $haystack contains at least one of the given needles; false otherwise, including when $haystack is null, when $needles is empty, and when every needle is an empty string.

Errors

Nothing. A null haystack returns false rather than raising a TypeError.

Str::contains wraps PHP's str_contains() with three things the native function lacks: an array of needles, a case-insensitive mode, and a safe response to null.

When to reach for it

Reach for it when you would otherwise write a chain of ||: checking whether a user agent mentions any of several bots, whether a MIME type is one of a set, whether a message body triggers any keyword in a moderation list. Passing the list as an array reads far better and short-circuits on the first hit.

Use ignoreCase: true as a named argument rather than positionally — it documents itself at the call site and survives future signature changes.

What trips people up

Empty needles are skipped. Str::contains('anything', '') is false, while PHP's native str_contains('anything', '') is true. If your needle comes from user input or config and can be blank, this quietly changes the answer — and an array containing one empty string behaves like an empty array.

It is a plain substring test, not a word-boundary test: Str::contains('classic', 'ass') is true. For patterns use Str::is; for word matching you still need a regex.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Check a user-agent string against a list of known crawler names in one call.
  • Decide whether an uploaded MIME type is any of several accepted image types.
  • Flag a comment when it contains any word from a moderation keyword list.

Frequently asked questions

How do I check if a string contains any of several values in Laravel?

Pass an array as the second argument: Str::contains($haystack, ['foo', 'bar']) returns true as soon as one of them is found.

Is Str::contains case sensitive?

Yes by default. Pass ignoreCase: true as a named argument to lower-case both sides with mb_strtolower before comparing.

Why does Str::contains return false for an empty needle?

Empty needles are explicitly skipped in the loop, unlike PHP's native str_contains() which treats '' as always present. Validate the needle before calling if it can be blank.

More examples

Matching any needle from a list

One call replaces three case-folded comparisons. ignoreCase is required here because the header says 'Googlebot' while the list is lower-cased; without it the first agent would report false.

Example · php
<?php

use Illuminate\Support\Str;

$bots = ['googlebot', 'bingbot', 'duckduckbot'];

$agents = [
    'Mozilla/5.0 (compatible; Googlebot/2.1)',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
];

foreach ($agents as $agent) {
    $isBot = Str::contains($agent, $bots, ignoreCase: true);

    echo $agent, ' => ', var_export($isBot, true), "\n";
}

// ... Googlebot/2.1) => true
// ... Mac OS X 10_15_7) => false

Guarding against a blank needle

Without the guard, a whitespace-only query returns false and the feature looks broken rather than misused. Making the empty case an explicit error surfaces the bug at the call site instead of in the UI.

Example · php
<?php

use Illuminate\Support\Str;

function highlightMatches(string $text, string $query): bool
{
    // A blank query would silently never match, so reject it explicitly.
    if (trim($query) === '') {
        throw new InvalidArgumentException('Search query may not be empty.');
    }

    return Str::contains($text, trim($query), ignoreCase: true);
}

var_dump(highlightMatches('Quarterly Revenue Report', 'revenue')); // true

try {
    highlightMatches('Quarterly Revenue Report', '   ');
} catch (InvalidArgumentException $e) {
    echo $e->getMessage(), "\n";
}

Discussion

  • Be the first to comment on this lesson.