mb_stristr
Returns the part of a string from the first case-insensitive match of a substring onward.
mb_stristr(string $haystack, string $needle, bool $before_needle = false, ?string $encoding = null): string|false- Added in PHP 5.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$haystack | string | The string to search in. |
$needle | string | The string to search for. May be empty as of PHP 8.0. |
$before_needleoptional | bool= false | When true, returns everything before the match instead of everything from the match onward. |
$encodingoptional | ?string= null | Character encoding. Null uses the internal encoding. |
Return value
string|falseThe portion of the haystack from (or before) the first match, or false if the needle is not found.
Errors
Throws a ValueError if encoding is not a valid encoding.
Changelog
- PHP 8.0.0needle now accepts an empty string.
- PHP 8.0.0encoding is nullable now.
mb_stristr() finds a substring case-insensitively and hands you back a slice of the original string rather than a number. By default that slice runs from the match to the end and includes the needle; pass true for before_needle and you get everything up to the match instead, excluding it.
When to reach for it
It shines when you want the text around a marker and do not care where the marker is. Pulling the value out of a Subject: ... line, taking the domain from an email address, splitting a sentence at the first keyword — all of these are one call instead of an mb_stripos() plus arithmetic plus mb_substr(). Because it is case-insensitive and Unicode-aware, it copes with headers that arrive as SUBJECT: or subject: and with needles containing accents.
What trips people up
The returned text keeps the original casing of the haystack — the case-insensitivity applies only to the matching, never to the output. People also forget that the default result includes the needle, so extracting a value after a delimiter usually means an extra mb_substr() to drop it.
And as always, an empty-string result is falsy while a genuine failure returns false; test with !== false.
Example
When to use it
- Extract the remainder of a header line after a case-varying label such as Subject: or subject:
- Grab the domain part of an email address by searching for '@'
- Take the text before the first occurrence of a keyword to build a lead-in snippet
Frequently asked questions
What is the difference between mb_stristr and mb_strstr?
mb_stristr matches case-insensitively using Unicode case folding; mb_strstr matches exactly. Both return the same kind of slice and both preserve the haystack's original casing in the output.
Does mb_stristr include the search term in the result?
Yes, by default the returned string starts with the match. Pass true as the third argument to get everything before the match instead, which excludes the needle.
Should I use mb_stristr or mb_stripos?
Use mb_stristr when you want the surrounding text, and mb_stripos when you want the numeric offset. mb_stristr avoids offset arithmetic entirely, which removes a common source of byte-versus-character bugs.
More examples
Pulling a value out of a labelled line
The first dump shows the whole line, because the needle is included and it sits at position 0. Trimming mb_strlen() of the needle off the front leaves 'Grüße aus München' — the extra step people forget when they expect mb_stristr to strip the marker.
<?php
mb_internal_encoding('UTF-8');
$header = 'BETREFF: Grüße aus München';
$rest = mb_stristr($header, 'betreff:');
var_dump($rest);
// drop the label itself
echo ltrim(mb_substr($rest, mb_strlen('betreff:'))), "\n";before_needle for the local part of an address
With before_needle true you get 'josé.pérez' without the @. The domain needs mb_substr to shave the leading @ off, and it comes back as 'Correo.example' with its original capitalisation intact.
<?php
mb_internal_encoding('UTF-8');
$addr = 'josé.pé[email protected]';
echo mb_stristr($addr, '@', true), "\n"; // local part
echo mb_substr(mb_stristr($addr, '@'), 1), "\n"; // domain
var_dump(mb_stristr($addr, '@') === false);
Discussion