webmozart/assert
Lightweight PHP assertion library for validating method input/output. Provides fast, readable checks via Webmozart\Assert\Assert with consistent error-message placeholders, throwing InvalidArgumentException on failure. Ideal for safer, less repetitive validation code.
if/throw checks or relying on PHP’s native is_* functions. It aligns with Laravel’s dependency injection (DI) and constructor validation patterns (e.g., Eloquent models, DTOs, or service constructors).positiveInteger($price)) must be enforced at the boundary. Integrates seamlessly with Laravel’s Form Requests or API resource validation.Validator (for HTTP requests) and FormRequest, this package is lighter and more performant for non-HTTP validation (e.g., internal service contracts, CLI commands, or background jobs).Validator which often generates generic messages.->rules() with Assert in boot() for complex validation logic.Assert::uuid($model->id)).Assert::isList($data['items'])).Assert::directory($path)).!empty($value)), the package may introduce unnecessary verbosity. Mitigate by documenting when to use Assert vs. native PHP.InvalidArgumentException (not Laravel’s ValidationException). Requires global exception handling (e.g., middleware or error handlers) to convert to API-friendly responses or CLI-friendly output.Assert::string() passes for null in some PHP versions). Mitigate with property-based testing (e.g., PestPHP).User::__construct()).setEmail()).OrderService::create()).StoreRequest::validate()).InvalidArgumentException to Laravel’s ValidationException for APIs.Assert::uuid() with malformed strings).Validator for HTTP-specific validation.Assert (if already using Symfony components).->rules() with Assert for non-HTTP validation (e.g., nested data, complex business rules).Assert::positiveInteger($this->price)).Assert::isList($resource->items)).Assert::directory($this->option('path'))).handle() methods (e.g., Assert::uuid($job->userId)).Assert::isInstanceOf($request->payload, UserDto::class)).if (!is_int($arg)) throw new Exception(...) with Assert::integer($arg).if checks in constructors/services with Assert.// Before
if (!is_int($userId) || $userId <= 0) {
throw new \InvalidArgumentException("Invalid user ID");
}
// After
Assert::positiveInteger($userId, 'User ID must be a positive integer');
public function boot()
{
$this->afterValidate(function (StoreRequest $request) {
Assert::minLength($request->title, 3, 'Title must be at least 3 characters');
});
}
is_int($arg) but no range checks.composer.json:
composer require webmozart/assert
app/Traits/ValidatesInput.php).use Webmozart\Assert\Assert;
trait ValidatesInput
{
protected function assertInteger($value, string $field): void
{
Assert::integer($value, "$field must be an integer");
}
}
InvalidArgumentException to ValidationException for APIs.// app/Exceptions/Handler.php
public function render($request, Throwable $exception)
{
if ($exception instanceof \Webmozart\Assert\InvalidArgumentException) {
return response()->json([
'message' => $exception->getMessage(),
'errors' => ['field' => $exception->getMessage()]
], 422);
}
return parent::render($request, $exception);
}
/**
* @param int $id Must be a positive integer (see Assert::positiveInteger)
*/
public function __construct(int $id)
{
Assert::positiveInteger($id);
$this->id = $id;
}
if/throw blocks.Assert::uuid() with invalid formats).Validator which may obscure the source).How can I help you explore Laravel packages today?