Str::endsWith

Determines whether a string ends with a given value, or with any value from an array.

Signature
Str::endsWith(string $haystack, string|iterable<string> $needles): bool

Parameters

ParameterTypeDescription
$$haystackstringThe string to test.
$$needlesstring|iterable<string>A single suffix, or any iterable of suffixes. The method returns true as soon as one of them matches.

Return value

booltrue if $haystack ends with at least one of the given needles; false otherwise, including when $haystack is null, when $needles is empty, and when every needle is an empty string.

Errors

Nothing. A null haystack returns false rather than raising a TypeError.

Str::endsWith wraps PHP's str_ends_with() and adds two things: it accepts an iterable of suffixes, and it returns false for a null haystack instead of throwing.

When to reach for it

Use it for suffix tests where several endings are acceptable — an upload whose name must end in one of ['.jpg', '.jpeg', '.png'], a path that may or may not already carry a trailing slash, a class name ending in Controller or Job. Passing the array replaces a chain of || and short-circuits on the first match.

What trips people up

Unlike Str::contains and Str::is, this method has no ignoreCase argument. A file uploaded as report.PDF fails Str::endsWith($name, '.pdf'), which is the single most common bug in extension checks written with it. Either lower-case the haystack yourself, or reach for Str::is('*.pdf', $name, ignoreCase: true).

Empty needles are skipped, so Str::endsWith('anything', '') is false where the native str_ends_with() is true. And do not use it for security decisions on filenames — extension checks are a convenience, not validation; verify the actual MIME type.

Example

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

When to use it

  • Accept an upload only when its filename ends in one of several image extensions.
  • Detect whether a base URL already carries a trailing slash before joining a path.
  • Route a class name by its suffix, such as anything ending in Controller or Job.

Frequently asked questions

Is Str::endsWith case insensitive?

No, and it has no ignoreCase argument. Lower-case the haystack with Str::lower() first, or use Str::is('*.ext', $value, ignoreCase: true).

Can Str::endsWith check several suffixes at once?

Yes. Pass an array or any iterable as the second argument and it returns true as soon as one of them matches the end of the string.

Why does Str::endsWith return false for an empty needle?

Empty needles are skipped by design, unlike PHP's native str_ends_with() which treats '' as always matching. Validate the needle before calling if it can be blank.

More examples

A case-safe extension check

Lowering the haystack once, rather than duplicating every extension in upper case, is what makes holiday.JPG pass. The extension list itself stays lower-case and readable.

Example · php
<?php

use Illuminate\Support\Str;

$images = ['.jpg', '.jpeg', '.png', '.webp'];

$uploads = ['holiday.JPG', 'diagram.png', 'notes.txt'];

foreach ($uploads as $name) {
    $ok = Str::endsWith(Str::lower($name), $images);

    echo str_pad($name, 14), var_export($ok, true), "\n";
}

// holiday.JPG   true
// diagram.png   true
// notes.txt     false

The same test with Str::is

When case-insensitivity is required, Str::is with a leading asterisk does the job endsWith cannot, at the cost of compiling a small regex per pattern. For hot loops, lower-casing once and using endsWith is faster.

Example · php
<?php

use Illuminate\Support\Str;

$name = 'holiday.JPG';

// endsWith cannot ignore case...
var_dump(Str::endsWith($name, '.jpg'));            // false

// ...but Str::is can, using an asterisk wildcard.
var_dump(Str::is('*.jpg', $name, ignoreCase: true)); // true

// And it accepts a list of patterns too.
var_dump(Str::is(['*.jpg', '*.png'], $name, ignoreCase: true)); // true

Discussion

  • Be the first to comment on this lesson.