Install the Package:
composer require apie/regex-value-objects
Ensure your composer.json includes PHP 8.3+ and apie/core (version-matched).
First Use Case: Create a value object for a specific validation need (e.g., email):
use Apie\RegexValueObjects\RegexValueObject;
class EmailAddress extends RegexValueObject
{
public function __construct(string $value)
{
parent::__construct($value, '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/');
}
}
Use it in a Laravel controller or service:
$email = new EmailAddress(request('email')); // Throws InvalidArgumentException if invalid
Where to Look First:
RegexValueObject (abstract base class with validation logic).RegexValueObjectTest.php to understand edge cases (e.g., regex failures, empty inputs).Value Object Creation:
Extend RegexValueObject for domain-specific rules:
class PhoneNumber extends RegexValueObject
{
public function __construct(string $value)
{
parent::__construct($value, '/^\+?[0-9\s\-\(\)]{10,}$/');
}
}
Integration with Laravel Validation: Create a custom validation rule:
use Apie\RegexValueObjects\RegexValueObject;
use Illuminate\Validation\Rule;
class RegexRule extends Rule
{
protected $pattern;
public function __construct(string $pattern)
{
$this->pattern = $pattern;
}
public function validate($attribute, $value, $fail)
{
try {
new RegexValueObject($value, $this->pattern);
} catch (\InvalidArgumentException $e) {
$fail($e->getMessage());
}
}
}
Use in FormRequest:
public function rules()
{
return [
'email' => ['required', new RegexRule('/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/')],
];
}
Domain-Driven Design (DDD) Workflow: Use value objects in domain services:
class UserService
{
public function createUser(array $data)
{
$email = new EmailAddress($data['email']);
$phone = new PhoneNumber($data['phone']);
// Proceed with business logic...
}
}
Model Casting: Cast attributes to value objects in Eloquent models:
use Illuminate\Database\Eloquent\Casts\Attribute;
protected function email(): Attribute
{
return Attribute::make(
get: fn ($value) => $value,
set: fn ($value) => new EmailAddress($value)
);
}
Input Sanitization Pipeline:
AppServiceProvider to validate incoming requests early.public function handle(Request $request, Closure $next)
{
$request->merge([
'email' => new EmailAddress($request->email),
]);
return $next($request);
}
API Contracts:
Testing:
public function testValidEmail()
{
$email = new EmailAddress('test@example.com');
$this->assertEquals('test@example.com', $email->value());
}
public function testInvalidEmail()
{
$this->expectException(InvalidArgumentException::class);
new EmailAddress('invalid-email');
}
Performance Optimization:
class EmailAddress extends RegexValueObject
{
private static $pattern;
public function __construct(string $value)
{
if (self::$pattern === null) {
self::$pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
}
parent::__construct($value, self::$pattern);
}
}
Error Handling:
public function __construct(string $value)
{
parent::__construct($value, '/pattern/', 'Invalid email format. Use format: user@example.com');
}
Laravel Service Providers:
$this->app->bind(EmailAddress::class, function () {
return new EmailAddress(request('email'));
});
Localization:
class PhoneNumber extends RegexValueObject
{
public function __construct(string $value, string $countryCode = 'US')
{
$pattern = $this->getPatternForCountry($countryCode);
parent::__construct($value, $pattern);
}
}
Regex Complexity:
Immutability:
$value property after instantiation will not update validation.public function value(): string { return $this->value; }
Laravel Validation Integration:
RegexRule) do not automatically integrate with Laravel’s validation error formatting.Illuminate\Validation\Validator to customize error messages:
Validator::extend('regex', function ($attribute, $value, $parameters, $validator) {
try {
new RegexValueObject($value, $parameters[0]);
return true;
} catch (\InvalidArgumentException $e) {
$validator->errors()->add($attribute, $e->getMessage());
return false;
}
});
Dependency Isolation:
apie/core, which may pull in unrelated functionality.replace directive to isolate dependencies:
"replacements": {
"apie/core": "self.version"
}
PHP 8.3+ Requirement:
No Native Laravel Support:
laravel-regex-value-objects) to abstract Laravel-specific logic.Regex Failures:
preg_last_error() to diagnose regex issues:
try {
$email = new EmailAddress($input);
} catch (\InvalidArgumentException $e) {
error_log('Regex error: ' . preg_last_error());
throw $e;
}
Performance Bottlenecks:
Unexpected Behavior:
isValid() method to explicitly check validity:
public function isValid(): bool
{
return $this->validate();
}
Default Patterns:
abstract class BaseValueObject extends RegexValueObject
{
protected function getEmailPattern(): string { return '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/'; }
}
Case Sensitivity:
How can I help you explore Laravel packages today?