mb_strripos

Finds the character position of the last case-insensitive match of a substring in a string.

Signature
mb_strripos(string $haystack, string $needle, int $offset = 0, ?string $encoding = null): int|false
  • Added in PHP 5.2.0

Parameters

ParameterTypeDescription
$haystackstringThe string to search in.
$needlestringThe string to search for. May be empty as of PHP 8.0.
$offsetoptionalint= 0Positive values begin the search that many characters into the haystack; negative values stop the search that many characters before the end.
$encodingoptional?string= nullCharacter encoding. Null uses the internal encoding.

Return value

int|falseThe character position of the last match, counted from the start of the haystack, or false if the needle is not found.

Errors

Throws a ValueError if offset is greater than the length of haystack, or 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_strripos() is the case-insensitive sibling of mb_strrpos(): it reports the position of the last match, counted in characters from the start of the string, ignoring case. The case folding is Unicode-aware, so Ü and ü, Σ and σ, and accented Latin pairs all match — something strripos() cannot do, since it only folds ASCII.

When to reach for it

Use it when the last occurrence matters and the input's casing is unreliable: finding the final ID: marker in a log line that may be written Id: or id:, locating the last extension separator in a filename that came from an uppercase-happy system, or trimming everything after the final keyword. As with all the position functions, if you actually want the surrounding text rather than a number, mb_strrichr() saves you the arithmetic.

What trips people up

The offset is asymmetric and unlike the one in mb_stripos(). A positive value starts the search that far into the haystack; a negative value does not start from the end — it stops the search that many characters before the end, hiding matches in the tail. Getting that backwards silently returns the wrong match.

And the return is still a falsy zero on a match at position 0, so compare with !== false.

Example

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

When to use it

  • Find the last case-varying marker in a log line so you can slice off the trailing payload
  • Locate the final extension separator in a filename normalised inconsistently for case
  • Trim everything after the last occurrence of a keyword regardless of how it was capitalised

Frequently asked questions

What is the difference between mb_strripos and mb_strrpos?

mb_strripos matches case-insensitively with Unicode case folding, mb_strrpos matches exactly. Both return the character position of the last match.

What does a negative offset do in mb_strripos?

It stops the search that many characters before the end of the haystack, so matches in the final section are ignored. This is different from mb_stripos, where a negative offset sets where the search starts.

Why does mb_strripos return a different number than strripos?

mb_strripos counts characters while strripos counts bytes, and strripos only folds ASCII case. On accented or non-Latin text the two disagree on both the position and whether there is a match at all.

More examples

Positive versus negative offset

The plain call finds the x at 5. Starting at 3 still finds 5, because a positive offset only sets where the search begins. The negative offset excludes the last three characters, so the match at 5 is hidden and the one at 3 is returned instead.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = 'aXbXcXd';

var_dump(mb_strripos($s, 'x'));      // last x
var_dump(mb_strripos($s, 'x', 3));   // start 3 chars in
var_dump(mb_strripos($s, 'x', -3));  // stop 3 chars before the end

Case-insensitive extension lookup

Each line prints the lowercased extension: pdf, gz and (none). The !== false guard matters here because the third filename has no dot at all, and a bare truthiness test would also have misread a name that began with a dot.

Example · php
<?php
mb_internal_encoding('UTF-8');
foreach (['Rapport.PDF', 'año.tar.GZ', 'noextension'] as $f) {
    $pos = mb_strripos($f, '.');
    echo $f, ' -> ';
    echo $pos === false ? "(none)\n" : mb_strtolower(mb_substr($f, $pos + 1)) . "\n";
}

Discussion

  • Be the first to comment on this lesson.