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.
Install the Package
composer require php-standard-library/comparison
No additional configuration is needed—Laravel’s autoloader will handle the rest.
First Use Case: Replace Ad-Hoc Comparisons
Replace repetitive if-else or ternary checks in controllers/services with the Comparator class.
use PhpStandardLibrary\Comparison\Comparator;
// Before (ad-hoc)
if ($user->role === 'admin') {
// Grant access
}
// After (standardized)
$comparator = new Comparator();
if ($comparator->equals($user->role, 'admin')) {
// Grant access
}
Key Entry Points
Comparator class: Core interface for all comparisons (e.g., equals(), greaterThan(), between()).Comparison facade (optional): Create a facade for cleaner syntax (see Implementation Patterns).ComparisonException: Handle edge cases (e.g., invalid types) gracefully.First Integration: Collections Replace manual sorting/filtering in Laravel Collections:
use PhpStandardLibrary\Comparison\Comparator;
$users = User::all();
$sorted = $users->sortBy(function ($user) {
return (new Comparator())->desc($user->created_at);
});
Centralize business logic comparisons in a service layer to avoid duplication.
class OrderService
{
private Comparator $comparator;
public function __construct()
{
$this->comparator = new Comparator();
}
public function isEligibleForDiscount(Order $order): bool
{
return $this->comparator->greaterThan($order->total, 100)
&& $this->comparator->equals($order->status, 'pending');
}
}
Extend Laravel Collections with comparator methods via a macro:
use Illuminate\Support\Collection;
use PhpStandardLibrary\Comparison\Comparator;
Collection::macro('sortByComparator', function ($key, $direction = 'asc') {
$comparator = new Comparator();
return $this->sortBy(function ($item) use ($key, $direction, $comparator) {
return $comparator->{$direction}($item->{$key});
});
});
// Usage
$users->sortByComparator('created_at', 'desc');
Use global query macros to adapt comparators to SQL:
use Illuminate\Database\Eloquent\Builder;
use PhpStandardLibrary\Comparison\Comparator;
Builder::macro('orderByComparator', function ($column, $direction = 'asc') {
$comparator = new Comparator();
// Note: This is a simplified example; SQL generation requires careful handling.
return $this->orderBy($column, $direction === 'asc' ? 'asc' : 'desc');
});
// Usage
User::query()->orderByComparator('age')->get();
Parse and apply comparator-based sorting/filtering in API requests:
use PhpStandardLibrary\Comparison\Comparator;
class SortableRequest
{
public function applyComparator(array $data): array
{
$comparator = new Comparator();
$sorted = [];
foreach ($data as $key => $value) {
if (str_contains($key, 'sort_')) {
$field = str_replace('sort_', '', $key);
$sorted[$field] = $comparator->{$value}($field);
}
}
return $sorted;
}
}
Extend the Comparator for custom domain logic (e.g., Money, DateRange):
use PhpStandardLibrary\Comparison\Comparator;
class MoneyComparator extends Comparator
{
public function greaterThan(Money $a, Money $b): bool
{
return $a->getAmount() > $b->getAmount();
}
}
// Usage
$moneyComparator = new MoneyComparator();
$moneyComparator->greaterThan($order->total, $threshold);
Create a facade to avoid instantiating Comparator repeatedly:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Facade;
use PhpStandardLibrary\Comparison\Comparator;
class ComparisonFacade extends Facade
{
protected static function getFacadeAccessor()
{
return new Comparator();
}
}
// Usage
if (Comparison::equals($user->role, 'admin')) { ... }
Use comparators in model accessors for derived attributes:
use PhpStandardLibrary\Comparison\Comparator;
class User extends Model
{
public function getIsPremiumAttribute(): bool
{
$comparator = new Comparator();
return $comparator->greaterThan($this->purchases, 10);
}
}
Add Blade directives or helpers for view comparisons:
// app/Helpers/ComparisonHelper.php
use PhpStandardLibrary\Comparison\Comparator;
if (!function_exists('compare')) {
function compare($a, $b, string $operator = 'equals')
{
$comparator = new Comparator();
return $comparator->{$operator}($a, $b);
}
}
// Blade usage
@if(compare($user->role, 'admin'))
<p>Admin Panel</p>
@endif
Use comparators in custom validation rules:
use PhpStandardLibrary\Comparison\Comparator;
use Illuminate\Validation\Rule;
class UpdateOrderRequest extends FormRequest
{
public function rules()
{
return [
'total' => [
'numeric',
Rule::function('max', function () {
$comparator = new Comparator();
return $comparator->greaterThan($this->threshold, 0)
? ['max' => $this->threshold]
: [];
}),
],
];
}
}
Apply comparators in event logic (e.g., filtering notifications):
use PhpStandardLibrary\Comparison\Comparator;
class SendNotificationListener
{
public function handle(OrderPlaced $event)
{
$comparator = new Comparator();
if ($comparator->greaterThan($event->order->total, 500)) {
Notification::send($event->user, new PremiumOrderNotification());
}
}
}
Comparator defaults to strict comparisons (===). Use notEquals() or looseEquals() explicitly for loose checks.null may throw exceptions or return unexpected results. Handle null cases explicitly:
$comparator->equals($user->role, 'admin'); // Throws if $user->role is null
Comparison::isNull() or provide default values:
$comparator->equals($user->role ?? 'guest', 'admin');
where()/orderBy() or use raw SQL when necessary.$comparator->greaterThan()) may be slower than native operators (>) in tight loops.string vs. int) may lead to bugs.if (!$a instanceof \DateTime || !$b instanceof \DateTime) {
throw new \InvalidArgumentException('Both values must be DateTime');
}
Comparison facade creates a new Comparator instance on every call. This is fine for most cases but may be inefficient in loops.Comparator to the container for reuse:
How can I help you explore Laravel packages today?