Str::replaceLast
Replaces only the final occurrence of a substring, leaving every earlier match untouched.
Str::replaceLast(string $search, string $replace, string $subject): string- Added in Laravel 5.3
Parameters
| Parameter | Type | Description |
|---|---|---|
$$search | string | The substring to find. Matched literally and case sensitively, never as a regular expression. |
$$replace | string | The text that takes the place of the final match. |
$$subject | string | The string being searched. |
Return value
stringThe subject with its final occurrence of $search replaced, or the untouched subject when $search does not appear.
Changelog
- PHP 9.xAn empty $search is now short-circuited and returns the subject unchanged instead of relying on strrpos behaviour.
Str::replaceLast finds the last literal occurrence of a needle and swaps just that one. Everything before it is left alone, which is the entire point: str_replace would hit every match, and that is usually the bug you are trying to avoid.
Reach for it when the meaningful token sits at the end of the string — the extension in a file path, the trailing slash on a URL, the final comma in a list you are rendering as prose. It is the mirror of Str::replaceFirst, and the pair exists because those two positions are where nearly all "replace exactly one occurrence" logic lives.
What trips people up
- The match is literal, not a pattern.
.,*and/carry no special meaning, so nothing needs escaping and no regex is possible. - It is case sensitive.
thewill not matchThe. - When the needle never appears you get the subject back verbatim, with no signal that nothing happened. Compare the result against the input if you need to know.
Internally it locates the byte offset with strrpos and splices with substr_replace, so UTF-8 subjects are safe as long as the needle is itself valid UTF-8.
Example
When to use it
- Rewrite a file's final extension, turning resources/views/home.php into resources/views/home.blade.php.
- Strip one trailing slash from a URL without disturbing the slashes inside the path.
- Turn the last comma of a generated list into ' and ' so it reads as a sentence.
Frequently asked questions
How is replaceLast different from str_replace in PHP?
str_replace replaces every occurrence, while Str::replaceLast replaces only the final one and returns the rest of the string untouched. Use str_replace when all matches should change and Str::replaceLast when the position of the match is what makes it the right one.
Does Str::replaceLast support regular expressions?
No, the search argument is matched literally via strrpos. Special characters such as dots, slashes and asterisks are compared as themselves, so nothing needs escaping; use preg_replace if you genuinely need a pattern.
Why did Str::replaceLast not change my string?
Either the needle does not appear in the subject, the case does not match, or the needle is an empty string. All three cases return the original subject silently, so compare the return value with the input to detect a miss.
More examples
Rendering a list as a sentence
Prints "apples, pears and plums", then "https://example.com/blog", then "a-b=c". The first line shows why the last-only behaviour matters: str_replace would have produced "apples and pears and plums". The third line shows that Str::of()->replaceLast() takes the same two arguments, with the subject supplied by the chain.
<?php
use Illuminate\Support\Str;
$fruit = ['apples', 'pears', 'plums'];
echo Str::replaceLast(', ', ' and ', implode(', ', $fruit)), PHP_EOL;
// Trim exactly one trailing slash, not every slash.
echo Str::replaceLast('/', '', 'https://example.com/blog/'), PHP_EOL;
// The fluent string object exposes the same method.
echo Str::of('a-b-c')->replaceLast('-', '='), PHP_EOL;Rewriting a path inside an application
Shows the typical shape in application code: only the trailing '.blade.php' is rewritten, so a directory named 'blade.php-archive' earlier in the path could never be corrupted. This snippet is not runnable on this page because storage_path() requires a booted application container.
<?php
namespace App\Support;
use Illuminate\Support\Str;
class ViewPath
{
public function toCompiled(string $path): string
{
// resources/views/mail/order.blade.php -> storage/framework/views/order.php
$file = Str::replaceLast('.blade.php', '.php', basename($path));
return storage_path('framework/views/'.$file);
}
}
echo (new ViewPath)->toCompiled('resources/views/mail/order.blade.php'), PHP_EOL;
Discussion