strrchr

Returns the part of a string from the last occurrence of a character to the end.

Signature
strrchr(string $haystack, string $needle, bool $before_needle = false): string|false
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$haystackstringThe string to search in.
$needlestringIf needle contains more than one character, only the first is used.
$before_needleoptionalbool= falseIf 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

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

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.