Str::after
Returns everything after the first occurrence of a value, or the whole string if it is absent.
Str::after(string $subject, string $search): stringParameters
| Parameter | Type | Description |
|---|---|---|
$$subject | string | The string to slice. |
$$search | string | The value to search for. Matching is case sensitive and only the first occurrence is used. |
Return value
stringThe remainder of $subject following the first occurrence of $search. If $search is an empty string, or does not appear in $subject, the entire $subject is returned unchanged.
Errors
Nothing. A missing search value is a normal result, not an error.
Internally this is explode($search, $subject, 2) with the last element taken, so it cuts at the first match and keeps everything to its right, including any delimiters that appear again later. Str::after('a/b/c', '/') is 'b/c', not 'c'.
When to reach for it
Use it when you want the tail of a string relative to a known marker and you do not care where that marker sits: pulling the token out of Bearer eyJhbG..., the domain out of an email address, the message out of a LEVEL: message log line.
What trips people up
The failure mode is silent. When $search is not in the subject you get the whole subject back, not null and not ''. Code like $domain = Str::after($input, '@') will happily hand you 'not-an-email' as a domain. If "not found" needs different handling, gate it with Str::contains first, or use str_contains() in a guard clause.
An empty $search short-circuits and also returns the subject, so a variable delimiter that happens to be blank will not throw — it will quietly do nothing.
Example
When to use it
- Strip a fixed prefix such as "Bearer " off an Authorization header value.
- Pull the domain half out of an email address at the first @.
- Get the message body from a log line formatted as "ERROR: something failed".
Frequently asked questions
Why does Str::after return the whole string instead of null?
Because it is documented to: when the search value is not found the entire subject is returned. Laravel does not signal a miss, so guard with Str::contains when "not found" needs its own branch.
Is Str::after case sensitive?
Yes. There is no ignoreCase argument. Normalise the subject with Str::lower() first, or match with Str::is() which does accept ignoreCase.
How do I get the text after the last occurrence instead of the first?
Use Str::afterLast(). Str::after always cuts at the first match, so 'a/b/c' gives 'b/c' while afterLast gives 'c'.
More examples
Extracting a bearer token
The first var_dump prints string(24) "eyJhbGciOiJIUzI1NiJ9.abc" — the 31-character header with the seven-character "Bearer " prefix removed; the second prints NULL. Without the Str::contains guard the Basic header would have returned itself in full and been treated as a valid token.
<?php
use Illuminate\Support\Str;
$header = 'Bearer eyJhbGciOiJIUzI1NiJ9.abc';
$token = Str::contains($header, 'Bearer ')
? Str::after($header, 'Bearer ')
: null;
var_dump($token);
// A header that is not a bearer token must not fall through.
$basic = 'Basic dXNlcjpwYXNz';
var_dump(Str::contains($basic, 'Bearer ') ? Str::after($basic, 'Bearer ') : null);First occurrence versus last
Shows why the two helpers are not interchangeable. For a path or a namespace you almost always want afterLast; after only removes the first segment.
<?php
use Illuminate\Support\Str;
$path = 'storage/app/public/avatars/user-1.png';
echo Str::after($path, '/'), "\n";
// app/public/avatars/user-1.png
echo Str::afterLast($path, '/'), "\n";
// user-1.png
$class = 'App\\Http\\Controllers\\UserController';
echo Str::after($class, '\\'), "\n";
// Http\Controllers\UserController
Discussion