strrchr
Returns the part of a string from the last occurrence of a character to the end.
strrchr(string $haystack, string $needle, bool $before_needle = false): string|false- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$haystack | string | The string to search in. |
$needle | string | If needle contains more than one character, only the first is used. |
$before_needleoptional | bool= false | If true, returns the part of the haystack before the last occurrence of the needle (excluding the needle). |
Return value
string|falseThe portion of the string, or false if needle is not found.
Changelog
- PHP 8.3.0The before_needle parameter was added.
- PHP 8.0.0needle now accepts an empty string.
- PHP 8.0.0Passing an int as needle is no longer supported.
strrchr() finds the last occurrence of a single character and returns everything from that character to the end of the string, including the character itself. Since PHP 8.3 you can pass before_needle: true to get everything before it instead.
When to reach for it
It is the shortest way to peel a trailing segment off a delimited string: the extension from a filename, the short class name from a fully qualified one, the last node of a dotted key. One call replaces the strrpos() plus substr() pair.
What trips people up
Only the first character of needle is used. strrchr($path, '/xyz') silently searches for / — there is no warning, so a multi-character needle that "works" is usually working by accident. Use strrpos() with substr() when the delimiter is longer than one byte.
The returned string includes the delimiter, so a file extension comes back as .txt, not txt. Strip it with substr($ext, 1).
When the character is absent the return is false, so test with === false before calling substr() on the result.
For real filesystem paths prefer pathinfo() and basename(): they understand the platform's separators and edge cases such as dotfiles.
Example
When to use it
- Extract a file extension from a name that may contain several dots, such as archive.tar.gz.
- Get the short class name from a fully qualified namespaced name.
- Take the last segment of a dotted configuration key like app.mail.host.
Frequently asked questions
What is the difference between strstr and strrchr?
strstr searches for the first occurrence of a whole substring; strrchr searches for the last occurrence of a single character. Both return the remainder of the string from that point.
How do I get a file extension in PHP?
substr(strrchr($file, '.'), 1) works for simple names, but pathinfo($file, PATHINFO_EXTENSION) is safer because it handles paths with no extension and directories containing dots.
Can strrchr search for more than one character?
No. Only the first character of the needle is used and the rest is silently ignored. Combine strrpos() with substr() for multi-character delimiters.
More examples
Only the first needle character counts
The second call gives the same answer as the first because only the leading slash of '/xyz' is used. basename() and pathinfo() produce the cleaner result for real paths, without the leading separator.
<?php
$path = 'a/b/c/file.txt';
echo strrchr($path, '/'), PHP_EOL; // /file.txt
echo strrchr($path, '/xyz'), PHP_EOL; // /file.txt — 'xyz' is ignored
echo basename($path), PHP_EOL; // file.txt
print_r(pathinfo($path));Short class name from a namespace
The first block prints Invoice and the second prints the containing namespace using the PHP 8.3 before_needle flag. The last check shows why the === false guard matters: an unqualified class name has no backslash, so strrchr returns false and the fallback keeps the original name.
<?php
$class = 'App\\Domain\\Billing\\Invoice';
$tail = strrchr($class, '\\');
echo $tail !== false ? substr($tail, 1) : $class, PHP_EOL; // Invoice
echo strrchr($class, '\\', true), PHP_EOL; // App\Domain\Billing
$plain = 'Invoice';
echo strrchr($plain, '\\') !== false ? 'namespaced' : 'global', PHP_EOL;
Discussion