php-standard-library/comparison
Small PHP comparison utilities that provide consistent, reusable ways to compare values. Useful for sorting, equality checks, and custom comparator functions without rewriting boilerplate across your projects.
Installation
composer require php-standard-library/comparison
The package is dependency-free and requires no additional configuration.
First Use Case: Replace Ad-Hoc Comparisons
Replace repetitive if statements or ternary checks in your Laravel controllers/services with the package’s methods.
use PhpStandardLibrary\Comparison\Comparator;
// Before
if ($user->role === 'admin') {
// Grant access
}
// After
$comparator = new Comparator();
if ($comparator->is($user->role, 'admin')) {
// Grant access
}
Key Entry Points
Comparator class: Core interface for all comparison logic.Comparison facade (optional): Create a facade for Laravel to simplify usage:
// app/Providers/AppServiceProvider.php
use PhpStandardLibrary\Comparison\Comparator;
use Illuminate\Support\Facades\Facade;
Facade::register('Comparison', function () {
return new Comparator();
});
Now use Comparison::is($a, $b) globally.First Integration: Collections Replace manual sorting in Laravel Collections:
// Before
$users->sortBy(function ($user) {
return $user->created_at->timestamp;
});
// After (using Comparator)
$users->sortByComparator('created_at', 'desc');
(Note: Requires extending the package or writing a helper—see Implementation Patterns.)
Centralize business logic comparisons in Laravel services:
class OrderService {
protected $comparator;
public function __construct(Comparator $comparator) {
$this->comparator = $comparator;
}
public function isEligibleForDiscount(Order $order) {
return $this->comparator->greaterThan($order->total, 100)
&& $this->comparator->is($order->user->role, 'premium');
}
}
Benefit: Single source of truth for comparison logic; easy to update rules.
Use global query macros to integrate comparators with Eloquent:
// app/Providers/AppServiceProvider.php
use Illuminate\Database\Eloquent\Builder;
Builder::macro('orderByComparator', function (Builder $query, $field, $direction = 'asc') {
$comparator = new Comparator();
// Note: This is a simplified example; actual SQL generation is non-trivial.
return $query->orderBy($field, $direction);
});
Usage:
User::orderByComparator('age')->get();
Caveat: SQL generation for complex comparators (e.g., between, contains) requires custom logic.
Extend Laravel Collections with comparator methods:
// app/Helpers/CollectionMacros.php
use Illuminate\Support\Collection;
use PhpStandardLibrary\Comparison\Comparator;
Collection::macro('sortByComparator', function ($field, $direction = 'asc') {
$comparator = new Comparator();
return $this->sortBy(function ($item) use ($field, $comparator, $direction) {
$value = $item->{$field};
return $direction === 'desc'
? $comparator->desc($value)
: $comparator->asc($value);
});
});
Usage:
$users = User::all()->sortByComparator('created_at', 'desc');
Parse and apply comparator-based sorting/filtering in API requests:
// app/Http/Requests/SortableRequest.php
use PhpStandardLibrary\Comparison\Comparator;
class SortableRequest extends FormRequest {
public function applyComparator(Collection $collection) {
$comparator = new Comparator();
if ($this->has('sort')) {
[$field, $direction] = explode(':', $this->sort);
return $collection->sortByComparator($field, $direction);
}
return $collection;
}
}
Usage in Controller:
$users = User::all();
$sortedUsers = $request->applyComparator($users);
Extend the Comparator for custom domain logic (e.g., Money, DateRange):
class MoneyComparator extends Comparator {
public function isGreaterThan(Money $a, Money $b) {
return $a->getAmount() > $b->getAmount();
}
}
Usage:
$moneyComparator = new MoneyComparator();
$moneyComparator->isGreaterThan($order->total, $threshold);
Bind the Comparator to Laravel’s container for dependency injection:
// app/Providers/AppServiceProvider.php
$this->app->bind(Comparator::class, function () {
return new Comparator();
});
Usage in Controllers:
public function __construct(private Comparator $comparator) {}
Create reusable Blade directives for comparisons:
// app/Providers/BladeServiceProvider.php
use Illuminate\Support\Facades\Blade;
Blade::directive('compare', function ($expression) {
return "<?php echo app(PhpStandardLibrary\Comparison\Comparator::class)->{$expression}; ?>";
});
Usage in Blade:
@compare("is($user->role, 'admin') ? 'Yes' : 'No'")
Use comparators in validation rules:
// app/Http/Requests/StoreOrderRequest.php
use PhpStandardLibrary\Comparison\Comparator;
public function rules() {
return [
'total' => [
'required',
function (Comparator $comparator, $attribute, $value) {
return $comparator->greaterThan($value, 0, "Total must be positive.");
},
],
];
}
Mock comparators in unit tests for deterministic behavior:
$mockComparator = Mockery::mock(Comparator::class);
$mockComparator->shouldReceive('is')
->with('admin', 'admin')
->andReturn(true);
$this->app->instance(Comparator::class, $mockComparator);
Comparator methods to SQL (e.g., between, contains) requires manual SQL writing or a query builder extension.// Custom query scope for 'between' comparator
User::whereBetweenComparator('age', [18, 30]);
Implement this via a query macro or scope:
Builder::macro('whereBetweenComparator', function ($field, array $range) {
return $this->whereBetween($field, $range);
});
null values explicitly, leading to unexpected behavior (e.g., Comparator::equals(null, null) might not return true as expected).Comparator or wrap calls:
$comparator->equals(
$value ?? null,
$expected ?? null
);
Comparator::greaterThan()) may introduce micro-overhead compared to native operators (>).$isValid = Cache::remember("discount.{$order->id}", now()->addHours(1), function () use ($comparator, $order) {
return $comparator->greaterThan($order->total, 100);
});
Comparator::equals("1", 1) returns false due to strict comparison).enum UserRole {
case ADMIN;
case USER;
}
$comparator->is($user->role, UserRole::ADMIN);
How can I help you explore Laravel packages today?