DEV Community

david duymelinck
david duymelinck

Posted on

How to validate constructor arguments when using constructor property promotion

I have written a post about the php 8.4 property hooks. Where I didn't understand what it did.

And I added validation code examples that have nothing to do with it. So I did rewrite the post. But I didn't want to lose the valid example code. And that is why this post exists.

What is the desired result?

We want to create a user by first and last name. The name parts should not be empty because we assume everyone has a first and last name.

Validation with a class method

class User { public function __construct(private string $firstName, private string $lastName) { $this->validate($firstName, 'firstName'); $this->validate($lastName, 'lastName'); } public function validate(string $value, $argumentName) { if (strlen($value) === 0) { throw new ValueError("$argumentName must be non-empty"); } } } 
Enter fullscreen mode Exit fullscreen mode

This is the method I use when there are one-off validations

Validation with trait

trait Validation { private function notEmpty(mixed $value, $argumentName) { if(is_string($value) && strlen($value) === 0) { throw new ValueError("$argumentName must be non-empty"); } } } class User { use Validation; public function __construct(private string $firstName, private string $lastName) { $this->notEmpty($firstName, 'firstName'); $this->notEmpty($lastName, 'lastName'); } } 
Enter fullscreen mode Exit fullscreen mode

This is the method that I use to centralize validation methods, because there are patterns that are recurring.

Validation with attributes

When your code has a lifecycle event in place that can process attributes, or you use a package like laravel-data. This is how the code might look like.

use Spatie\LaravelData\Data; class User extends Data { public function __construct( #[Min(1)] private string $firstName, #[Min(1)] private string $lastName ) {} } 
Enter fullscreen mode Exit fullscreen mode

When I have multiple cases with multiple repeating patterns, then this is the method I use.

Top comments (1)

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

I like using the last one. While the attributes of the User class describes which rules the properties must match , an external service is in charge of performing the validations.