Have you noticed that Laravel 10 came with a big skeleton rewriting to use PHP types everywhere - for parameters, properties, variables, and method returns. But let's explore what are the possible types and their syntax details.
Let's look at two code samples:
Without types:
class UserService { public $data; public function processData($user) { // ... }}
With types:
use App\Models\User; class UserService { public array $data; public function processData(User $user): User { // ... }}
The second example is more readable, right? If a developer opens the first example for the first time, he would have questions like "What is $data?" and "What exactly should I pass into $user".
The second code snippet specifies that we're working with arrays and User models.
Of course, many of these issues can be solved by just naming things more clearly, but variable/return types may also help massively.
But it's not just for readability. The practical usage is that PHP would throw errors if the variable of the wrong type is passed.
Here's a list of types from PHP 7:
Then, PHP 8 introduced static
and mixed
types. The static
type can only be used as a return type, and mixed
can be a return and property type.
The static
return type is used with fluent methods when returning $this
or static methods that return an instance of the class itself.
public function mutateRecordDataUsing(?Closure $callback): static{ $this->mutateRecordDataUsing = $callback; return $this;}
Then, PHP 8.1 introduced the never
return type. The method with the never
return type cannot return anything. It should throw an Exception or terminate with a die
/exit
call.
function redirect(string $url): never { header('Location: ' . $url); exit();}
In addition to the PHP types, you may use Laravel classes as types, like in the example above with (User $user)
.
On top of that, Laravel would help you with initializing and auto-resolving the variable of Controllers if you put the parameter with type:
use App\Services\UserService; class UserController{ public function index(UserService $service) { // With that parameter, under the hood, Laravel performs: // $service = new UserService(); $service->getUsers(); }}
You may sometimes see this syntax: ?string $variable
. This question mark signifies that the variable or return type can also be a null.
For example, in Filament, you can set the polling interval for charts as a string. But also, it can be set to null so that polling wouldn't happen.
protected static ?string $pollingInterval = '10s';
You may sometimes see this syntax: function something(int|array|string $var)
. It is called Union Types and can be used for properties, function parameters, and return types.
This example shows that $noSearchResultsMessage
can have more than one type, and the method to set the $noSearchResultsMessage
accepts more than one type.
trait CanBeSearchable{ // ... protected string | Htmlable | Closure | null $noSearchResultsMessage = null; public function noSearchResultsMessage(string | Htmlable | Closure | null $message): static { $this->noSearchResultsMessage = $message; return $this; } // ...}
PHP has a reputation for "automatically converting everything to everything".
When comparing, there are two ways: loose comparison (==
) and strict comparison (===
).
For example:
$a = 5;$b = "5"; var_dump($a == $b); // truevar_dump($a === $b); // false
Because the $b
variable is a string, the strict comparison returns false.
But there can be cases when the variable type isn't the expected. For such cases, the variable can be cast.
For example:
$a = 5;$b = "5"; var_dump($a === (int)$b); // true
Now, we get true because we tell PHP to make $b
as an integer.