Validator

The Validator class provides a centralized mechanism for data integrity. It handles everything from simple type casting and string sanitization to complex validation via rule chains.

Recommendation: Prefer the Rule builder over raw pipe strings for: IDE autocompletion, easy discovery of rules, and safer refactors (no typos like min:3 vs mix:3). You can still use strings (or arrays) when rules must be dynamically assembled at runtime.

Identity & Strings

string($value, bool $escapeHtml = true): string

Sanitizes input to a string. Trims whitespace and converts special chars to HTML entities (unless $escapeHtml is false).

email($value): ?string

Validates an email address. Returns null if invalid.

url($value): ?string

Validates a URL. Returns null if invalid.

ip($value): ?string

Validates an IP address. Returns null if invalid.

uuid($value): ?string

Validates standard UUID format.

ulid($value): ?string

Validates ULID (Universally Unique Lexicographically Sortable Identifier).

cuid($value) / cuid2($value): ?string

Validates Collision-resistant Unique Identifiers (v1 and v2).

emojis(string $content): string

Converts shortcodes (e.g., :smile:) into unicode emoji.

Numbers & Math

Leverages Brick\Math for high-precision operations.

int($value): ?int
Standard integer validation/casting. Returns null if invalid.
float($value): ?float
Standard float validation/casting. Returns null if invalid.
bigInt($value): ?BigInteger
Converts value to Brick\Math\BigInteger. Useful for values larger than PHP_INT_MAX.
decimal($value, int $scale = 30): ?BigDecimal
Converts value to Brick\Math\BigDecimal with strict precision scaling.
bytes($value): ?string
Validates byte size strings (e.g. 10MB, 512KB).

Structure & Logic

json($value): string

Validates JSON strings or safely encodes arrays to JSON. If $value is a string and invalid JSON, returns an error message string.

boolean($value): ?bool

Smart boolean casting (handles "true", "1", "on", "yes").

enum($value, array $allowed): bool

Checks if $value exists within a simple array of allowed options.

enumClass($value, string $class)

Validates against a PHP BackedEnum class. Supports single values or arrays of values. Returns backed value(s) or null when invalid.

date($value, string $format = "Y-m-d"): ?string

Validates and formats a date string (or DateTime) using the provided format.

dateTime($value, string $format = "Y-m-d H:i:s"): ?string

Validates and formats date-time values. Returns null for empty/invalid inputs.

Rule-Based Validation

withRules($value, string|Rule|array $rules, $confirm = null)

Evaluates a value against a set of rules. Returns:

  • true when all rules pass
  • string error message when the first rule fails

1) Rule Builder (Recommended)

Best developer experience: autocompletion, chaining, and discoverability.

use PP\Rule;

$rules = Rule::required()
    ->min(3)
    ->max(50)
    ->startsWith("J");

2) String Pipe Syntax

Useful for quick inline validation or when rules are loaded from config/database.

$rules = "required|min:3|max:50|startsWith:J";

3) Array Syntax

Great when conditionally appending rules without string concatenation.

$rules = ["required", "min:3", "max:50", "startsWith:J"];

Why the Rule builder is preferred

Autocomplete & discovery

Your IDE will show ->min(), ->email(), ->uuid() etc. You don’t need to memorize string spellings.

Safer refactors

Renaming/adding rules stays inside Rule.php methods. Strings can silently break via typos and won’t be caught until runtime.

Composable rules

Merge rule sets cleanly via Rule::required()->merge($other) instead of manual string concatenation.

Readable intent

Rule::required()->email() reads like a spec. Long pipe strings can be harder to scan in reviews.

Available Rules

These can be written as pipe strings (e.g. "min:3") or built via Rule methods (e.g. Rule::make()->min(3)).

required min:n max:n size:n between:min,max email url ip uuid ulid cuid int float boolean startsWith:s endsWith:s confirmed in:a,b,c notIn:a,b,c date:format dateFormat:format before:date after:date json timezone regex:pattern digits:n digitsBetween:min,max extensions:jpg,png mimes:image/jpeg,image/png file

Usage Examples

Example 1 — Basic casting & identity helpers

string / email / int
<?php
use PP\Validator;

$name  = Validator::string("  John  ");    // "John"
$age   = Validator::int("25");             // 25
$email = Validator::email("invalid");      // null

if ($email === null) {
    echo "Invalid email";
}
?>

Example 2 — Recommended: Rule builder (autocomplete)

Rule::required()->min()->max()

This is the recommended approach for most application validation because it’s typed-by-method and easy to navigate.

<?php
use PP\Validator;
use PP\Rule;

$inputName = "John";

$rules = Rule::required()
    ->min(3)
    ->max(50);

$result = Validator::withRules($inputName, $rules);

if ($result === true) {
    echo "✅ Valid name";
} else {
    // $result is the error string from the first failing rule
    echo "❌ " . $result;
}
?>

Example 3 — String pipe syntax (quick + dynamic)

"required|min:3|max:50"

Strings are still supported and can be useful when building rules from configuration, database, or user-defined constraints.

<?php
use PP\Validator;

$inputName = "Jo";

$rules = "required|min:3|max:50";
$result = Validator::withRules($inputName, $rules);

echo $result === true ? "✅ OK" : "❌ " . $result;
?>

Example 4 — Array rules (conditional composition)

["required", "min:8", ...]
<?php
use PP\Validator;

$password = "secret123";
$confirm  = "secret123";

$rules = ["required", "min:8"];

// conditionally add rules
$rules[] = "confirmed";

$result = Validator::withRules($password, $rules, $confirm);

echo $result === true ? "✅ Password OK" : "❌ " . $result;
?>

Example 5 — Merging Rule sets (reuse + consistency)

Rule::merge()

Build reusable rule blocks once, then merge them everywhere (keeps validation consistent across forms).

<?php
use PP\Validator;
use PP\Rule;

$nameRules = Rule::required()->min(3)->max(50);

$emailRules = Rule::required()->email();

$profileRules = Rule::make()
    ->merge($nameRules)
    ->merge($emailRules);

// Note: withRules validates a *single* value.
// Use merge for building consistent rulesets, then apply per-field:
$nameResult  = Validator::withRules("John", $nameRules);
$emailResult = Validator::withRules("john@example.com", $emailRules);

echo ($nameResult === true && $emailResult === true) ? "✅ Profile valid" : "❌ Invalid";
?>

Operational Notes

  • Return contract: Validator::withRules() returns true or an error string. Always use strict checks: === true.
  • Confirmation rule: confirmed compares the third parameter ($confirm) against the value.
  • Regex rule: pass full patterns including delimiters (example: regex:/^[a-z]+$/i).
  • Dynamic rules: if rules depend on runtime variables, array syntax is often the cleanest (append rules conditionally without string concatenation).