coduo/php-matcher
Flexible PHP pattern-matching library for testing and validating complex data structures. Compare arrays, JSON and objects against readable expectations, with rich mismatch descriptions to pinpoint differences. Useful for API response assertions and custom validation rules.
Installation Add via Composer (PHP 8.3+ required):
composer require coduo/php-matcher
No additional configuration is needed—it’s a drop-in package.
Basic Usage
Import the Matcher class and define a pattern:
use Coduo\Matcher\Matcher;
$matcher = new Matcher();
$pattern = [
'name' => 'John Doe',
'age' => 30,
'address' => [
'street' => '123 Main St',
'city' => 'Anywhere'
]
];
$data = [
'name' => 'John Doe',
'age' => 30,
'address' => [
'street' => '123 Main St',
'city' => 'New York'
]
];
$result = $matcher->match($pattern, $data);
First Use Case: Validation Quickly validate API responses or form submissions:
if ($matcher->match($expectedStructure, $actualData)) {
// Data matches expected structure
}
Structural Validation
Use match() to verify nested arrays/objects:
$pattern = [
'user' => [
'id' => 1,
'roles' => ['admin', 'editor']
]
];
Partial Matching
Use partialMatch() to ignore extra fields:
$matcher->partialMatch($pattern, $data); // Only checks if $pattern keys exist in $data
Dynamic Patterns
Combine with Laravel’s collect() for reusable validation:
$pattern = collect($expected)
->only(['id', 'name', 'metadata'])
->toArray();
Integration with Laravel Requests Validate incoming requests:
public function store(Request $request) {
$pattern = [
'title' => 'string',
'price' => 'float',
'tags' => ['string']
];
if (!$matcher->match($pattern, $request->all())) {
return response()->json(['error' => 'Invalid data'], 400);
}
}
Testing Assert data structures in PHPUnit:
$this->assertTrue($matcher->match($expected, $actual));
Strict vs. Loose Matching
looseMatch() to ignore types (e.g., 30 vs "30").Nested Arrays
$data has ['items' => [1, 2]], the pattern must include ['items' => [int, int]].Wildcards
'*' to match any value (e.g., ['name' => '*']).Performance
PHP Version Compatibility
Custom Matchers
Extend Matcher to add domain-specific rules:
class CustomMatcher extends Matcher {
public function matchEmail($pattern, $data) {
return filter_var($data, FILTER_VALIDATE_EMAIL) !== false;
}
}
Laravel Service Provider
Bind Matcher globally:
$this->app->singleton(Matcher::class, function () {
return new Matcher();
});
Then inject via constructor:
public function __construct(private Matcher $matcher) {}
Error Handling
Use getErrors() to debug mismatches:
$matcher->match($pattern, $data);
if ($matcher->hasErrors()) {
dd($matcher->getErrors());
}
php-matcher for structural checks, then Validator for business rules.config/matcher.php file for reusability.null values, and mixed types explicitly.How can I help you explore Laravel packages today?