Skip to content

Assertion Chains

Assertion chains provide a fluent interface for validating values with multiple assertions.

Instead of multiple static calls:

Assertion::string($email);
Assertion::notEmpty($email);
Assertion::email($email);

Use a fluent chain:

Assert::that($email)
->string()
->notEmpty()
->email();
use Cline\Assert\Assert;
Assert::that($value)
->assertion1()
->assertion2()
->assertion3();
Assert::that($age, 'Age must be valid')
->integer()
->greaterOrEqualThan(18);
Assert::that($user->email, null, 'user.email')
->notEmpty()
->email();

Skip all subsequent assertions if the value is null:

Assert::thatNullOr($middleName)
->string()
->minLength(2)
->maxLength(50);
// Equivalent to:
if ($middleName !== null) {
Assert::that($middleName)
->string()
->minLength(2);
}

Validate every element in an array:

Assert::thatAll($emailList)->email();
Assert::thatAll($userIds)
->integer()
->greaterThan(0);
Assert::that($username)
->string()
->notEmpty()
->minLength(3)
->maxLength(20)
->regex('/^[a-z0-9_]+$/');
Assert::that($price)
->float()
->greaterThan(0, 'Price must be positive')
->lessThan(1000000, 'Price too high');
Assert::that($email)
->string()
->notEmpty('Email is required')
->email('Invalid email format')
->maxLength(255, 'Email too long');
Assert::that($password)
->string()
->minLength(8, 'Password must be at least 8 characters')
->regex('/[A-Z]/', 'Must contain uppercase letter')
->regex('/[a-z]/', 'Must contain lowercase letter')
->regex('/[0-9]/', 'Must contain number');
Assert::that($user)
->notNull('User not found')
->isObject()
->isInstanceOf(User::class)
->propertyExists('email');
Assert::that($items)
->isArray()
->notEmpty('Items cannot be empty')
->minCount(1)
->maxCount(100);
// Required field
Assert::that($email)->notEmpty()->email();
// Optional field (can be null)
Assert::thatNullOr($phoneNumber)
->string()
->e164('Invalid phone format');
Assert::thatNullOr($config['timeout'])
->integer()
->greaterThan(0);
Assert::thatAll($recipientEmails)
->email('All recipients must have valid emails');
Assert::thatAll($quantities)
->integer()
->greaterThan(0);
Assert::thatAll($tags)
->string()
->notEmpty()
->minLength(2)
->maxLength(30);
Assert::that($email)
->notEmpty() // "Value is required"
->email(); // "Value is not a valid email"
Assert::that($password)
->notEmpty('Password is required')
->minLength(8, 'Password must be at least 8 characters');
Assert::that($username, 'Username is invalid')
->notEmpty()
->minLength(3);
// Good order: type → null/empty → format → constraints
Assert::that($email)
->string() // 1. Type check first
->notEmpty() // 2. Then null/empty
->email() // 3. Then format
->maxLength(255); // 4. Finally constraints
Assert::that($count)
->integer() // Ensures numeric operations work
->greaterThan(0);
Assert::that($name)
->string()
->notEmpty()
->minLength(2)
->maxLength(100)
->regex('/^[\p{L}\s]+$/u', 'Name can only contain letters');
// Bad - length check before type check
Assert::that($name)
->minLength(3)
->string();
// Good - type check first
Assert::that($name)
->string()
->minLength(3);