str

Create a fluent Stringable from a string, or a proxy to the static Str methods.

Signature
str(string|null $string = null): \Illuminate\Support\Stringable|object
  • Added in Laravel 9.0

Parameters

ParameterTypeDescription
$stringoptionalstring|null= nullThe string to wrap. Omitting the argument entirely returns the static-forwarding proxy; explicitly passing null returns a Stringable wrapping an empty string.

Return value

\Illuminate\Support\Stringable|objectA Stringable wrapping the given string. Called with no arguments at all, it returns a proxy object that forwards method calls to the static Str class.

str() is the shorthand for Str::of(). It returns an Illuminate\Support\Stringable, which wraps the value and exposes every Str method as a chainable instance method — trim, slug, camel, replace, before, after, limit, mask, whenContains and the rest.

Why chain instead of nest

The usual alternative is a stack of nested calls read inside-out: Str::slug(Str::lower(trim($x))). The Stringable version reads left to right in execution order, which is the whole point.

Getting a string back out

A Stringable is an object, not a string. It has __toString(), so echo, interpolation and loose == comparison all work — but a strict === against a string is false, and a string parameter type will only accept it because of coercion. Call ->toString() or cast with (string) when you need a real string, and note that methods like contains() and isEmpty() already return booleans, not Stringables.

The no-argument form

str() with no arguments gives you an object whose method calls forward to the static Str class, so str()->snake('FooBar') works. It is a convenience for avoiding the use statement, not a different API.

Example

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

When to use it

  • Build a URL slug from raw user input in one left-to-right chain.
  • Extract and reformat part of a string, such as the local part of an email address.
  • Apply a conditional transformation with whenContains or when without breaking the chain.

Frequently asked questions

What is the difference between str() and Str::of()?

Nothing functionally — str('x') is Str::of('x'). The helper is global so it needs no use statement, which matters most in Blade templates and short scripts.

How do I turn a Stringable back into a plain string?

Call ->toString(), cast with (string), or just echo it — Stringable implements __toString(). You need an explicit conversion before a strict === comparison, an in_array with strict mode, or json_encode of the object itself.

What does str() return when called with no arguments?

An anonymous proxy object whose method calls forward to the static Illuminate\Support\Str class, so str()->snake('FooBar') works. It is not an instance of Str, so do not test it with instanceof.

More examples

Chaining beats nesting

Both produce the same string; the chained form states the steps in the order they happen. toString() is called explicitly so the strict === comparison against the nested result succeeds.

Example · php
<?php

$title = '  The Quick Brown Fox!  ';

// Nested: read inside-out.
$nested = \Illuminate\Support\Str::limit(\Illuminate\Support\Str::slug(trim($title)), 15, '');

// Chained: read left to right.
$chained = str($title)->trim()->slug()->limit(15, '')->toString();

var_dump($nested === $chained);
echo $chained, "\n";
// bool(true)
// the-quick-brown

Stringable is an object, not a string

The === row is the one that catches people, usually in a test assertion or an in_array with strict mode. Predicate methods such as contains() and length() deliberately end the chain and return scalars.

Example · php
<?php

$s = str('taylor');

var_dump($s == 'taylor');            // bool(true)  - loose, uses __toString
var_dump($s === 'taylor');           // bool(false) - it is an object
var_dump($s->toString() === 'taylor'); // bool(true)

// Some methods leave the chain on purpose.
var_dump($s->contains('lor'));       // bool(true)  - a plain bool
var_dump($s->length());              // int(6)
var_dump(get_class($s->upper()));    // Stringable - still chainable

// json_encode sees an object unless you cast.
echo json_encode(['name' => (string) $s]), "\n";
// {"name":"taylor"}

Conditional transforms in a chain

when() keeps a branch inside the chain instead of forcing a temporary variable and an if. The condition receives the current Stringable, so the check and the transform both stay in one expression.

Example · php
<?php

$names = ['ACME_CORP', 'widgets ltd', 'Foo & Bar'];

foreach ($names as $name) {
    echo str($name)
        ->trim()
        ->when(
            fn ($s) => $s->upper()->exactly($s->toString()),
            fn ($s) => $s->lower()   // shouty input gets calmed down
        )
        ->replace('&', 'and')
        ->slug(), "\n";
}
// acme-corp
// widgets-ltd
// foo-and-bar

Discussion

  • Be the first to comment on this lesson.