literal

Builds an stdClass from named arguments for a quick, throwaway value object.

Signature
literal(mixed ...$arguments): mixed
  • Added in Laravel 11.0

Parameters

ParameterTypeDescription
$...$argumentsoptionalmixedNamed arguments become properties of the returned object. A single positional argument is returned unchanged.

Return value

mixedAn stdClass whose properties are the named arguments, or the single argument itself when exactly one positional argument is given.

Errors

Nothing.

Changelog

  • PHP 11.0Introduced. Not available in Laravel 10.x or earlier.

literal() turns named arguments into an stdClass: literal(name: 'Joe', age: 40) produces the same object as (object) ['name' => 'Joe', 'age' => 40]. The gain over the cast is readability — keys are written as PHP identifiers rather than quoted strings, and the call lines up visually like a constructor.

When to reach for it

Test fixtures, small view models assembled in a controller, and anywhere you want dot access such as $row->total without declaring a class for it. It pairs well with Collection::map() when you are reshaping rows before handing them to a template.

What trips people up

Passing a single positional argument returns that argument unchanged — no object is built. literal('hello') is just 'hello'. This is deliberate, so the helper can act as a no-op wrapper, but it means a lone unnamed value is never boxed. A single named argument does produce an object, and two or more positional arguments produce an object with numeric property names, which is almost never what you want.

The result is a plain stdClass: no type checking, no methods, and nested arrays stay arrays rather than becoming objects too.

Example

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

When to use it

  • Assemble a small view model in a controller without declaring a DTO class.
  • Create readable test fixtures where each field is named at the call site.
  • Reshape collection rows into objects so a Blade template can use arrow access.

Frequently asked questions

How do I create an stdClass with named arguments in PHP?

Call literal(name: 'Joe', age: 40), available since Laravel 11.0. It is equivalent to (object) ['name' => 'Joe', 'age' => 40] but the keys are written as identifiers, so an editor can align them and a typo is easier to spot.

Why did literal() return a string instead of an object?

Because you passed exactly one positional argument, and in that case literal() returns the argument unchanged rather than boxing it. Name the argument — literal(value: 'hello') — to get an stdClass back.

Does literal() convert nested arrays into objects?

No, it only casts the top level, so a nested array remains an array and must be read with square brackets. Nest another literal() call for the inner value if you want arrow access throughout.

More examples

Positional versus named arguments

The early return only fires when there is exactly one argument and the argument list is a list — that is, positional. One named argument skips it and gives you an object, and two positional arguments give you an object with the numeric property names 0 and 1, which you can only read with $obj->{0}.

Example · php
<?php

var_dump(literal('hello'));           // string(5) "hello" — returned as-is
var_dump(literal(value: 'hello'));    // object(stdClass) { value => "hello" }
var_dump(literal('a', 'b'));          // object(stdClass) { 0 => "a", 1 => "b" }
var_dump(literal());                  // object(stdClass) {}

Reshaping rows for a view

Each row becomes an object with exactly the two fields the template needs, computed once. Blade can then write {{ $line->total }} instead of {{ $line['total'] }}, which matters when the same partial also receives real Eloquent models.

Example · php
<?php

$rows = collect([
    ['sku' => 'A-1', 'qty' => 2, 'price' => 500],
    ['sku' => 'B-7', 'qty' => 1, 'price' => 1250],
]);

$lines = $rows->map(fn (array $r) => literal(
    sku: $r['sku'],
    total: $r['qty'] * $r['price'],
));

echo $lines->sum(fn (object $l) => $l->total), "\n";   // 2250
echo $lines->first()->sku, "\n";                       // A-1

Nested arrays stay arrays

literal() casts only the top level, so a nested array is still an array and $obj->meta->role silently fails. Either use array access for the inner value or nest a second literal() call, as the last two lines show.

Example · php
<?php

$obj = literal(name: 'Joe', meta: ['role' => 'admin']);

echo $obj->name, "\n";             // Joe
echo $obj->meta['role'], "\n";     // admin — array access, not ->role
var_dump(isset($obj->meta->role)); // bool(false)

// Nest another literal() call if you want objects all the way down.
$deep = literal(name: 'Joe', meta: literal(role: 'admin'));
echo $deep->meta->role, "\n";      // admin

Discussion

  • Be the first to comment on this lesson.