Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Comparison Laravel Package

phrity/comparison

Lightweight PHP interfaces and a helper trait for object comparisons. Implement Equalable/Comparable (or just compare() via ComparisonTrait) to get equals/greater/less helpers, plus a Comparator utility for sorting and filtering. Compatible with PHP 7.1+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the package:
    composer require phrity/comparison
    
  2. Implement Comparable or Equalable in your model/DTO:
    use Phrity\Comparison\{Comparable, ComparisonTrait};
    
    class Product implements Comparable
    {
        use ComparisonTrait;
    
        public function compare($compare_with): int
        {
            return $this->price <=> $compare_with->price;
        }
    }
    
  3. Use the Comparator for sorting/filtering:
    $products = [new Product(100), new Product(50)];
    $comparator = new \Phrity\Comparison\Comparator($products);
    $sorted = $comparator->sort(); // Ascending
    $filtered = $comparator->greaterThan($products[0]); // Products > $50
    

First Use Case

Sort a Laravel Collection of Eloquent models:

use Phrity\Comparison\{Comparable, ComparisonTrait};

class User extends Model implements Comparable
{
    use ComparisonTrait;

    public function compare($compare_with): int
    {
        return $this->created_at <=> $compare_with->created_at;
    }
}

// Usage:
$users = User::all();
$comparator = new \Phrity\Comparison\Comparator($users->toArray());
$sortedUsers = $comparator->sort(); // Sorted by creation date

Implementation Patterns

Core Workflows

1. Trait-Based Implementation (Recommended)

  • Use ComparisonTrait to auto-implement Comparable methods with a single compare() method.
  • Ideal for Eloquent models, DTOs, or value objects.
class Order implements Comparable
{
    use ComparisonTrait;

    public function compare($compare_with): int
    {
        return $this->total <=> $compare_with->total;
    }
}

2. Interface-Only Implementation

  • Implement Comparable/Equalable manually for fine-grained control.
  • Useful for legacy code or partial trait adoption.
class Category implements Comparable
{
    public function equals($compare_with): bool
    {
        return $this->id === $compare_with->id;
    }

    public function compare($compare_with): int
    {
        return strcmp($this->name, $compare_with->name);
    }

    // Implement remaining Comparable methods...
}

3. Comparator for Collections

  • Sorting:
    $comparator = new \Phrity\Comparison\Comparator($models);
    $ascending = $comparator->sort();       // Ascending
    $descending = $comparator->rsort();     // Descending
    
  • Filtering:
    $expensive = $comparator->greaterThan($thresholdModel);
    $recent = $comparator->lessThanOrEqual($cutoffModel);
    
  • Min/Max:
    $cheapest = $comparator->min();
    $mostRecent = $comparator->max();
    

4. Integration with Laravel Collections

  • Extend Illuminate\Support\Collection to use Comparator:
    use Phrity\Comparison\Comparator;
    
    class ComparableCollection extends \Illuminate\Support\Collection
    {
        public function sortByComparator(): self
        {
            return $this->sort(fn ($a, $b) => $a->compare($b));
        }
    }
    
  • Usage:
    $collection = new ComparableCollection($models);
    $sorted = $collection->sortByComparator();
    

5. Dynamic Comparison Logic

  • Use closures or strategies for context-aware comparisons:
    $comparator = new Comparator();
    $sortedByPrice = $comparator->sort($products, fn ($a, $b) => $a->price <=> $b->price);
    $sortedByName = $comparator->sort($products, fn ($a, $b) => strcmp($a->name, $b->name));
    

Laravel-Specific Patterns

1. Eloquent Model Integration

  • Add Comparable to models for database-agnostic sorting:
    class Product extends Model implements Comparable
    {
        use ComparisonTrait;
    
        public function compare($compare_with): int
        {
            return $this->price <=> $compare_with->price;
        }
    }
    
  • Use in API resources or services:
    $products = Product::all();
    $comparator = new Comparator($products);
    $sorted = $comparator->sort();
    

2. Query Builder Extensions

  • Create a macro for Comparator-like filtering:
    use Illuminate\Database\Eloquent\Builder;
    
    Builder::macro('whereGreaterThan', function ($field, $condition) {
        return $this->where($field, '>', $condition->$field);
    });
    
  • Usage:
    $expensive = Product::whereGreaterThan('price', $thresholdProduct);
    

3. Form Request Validation

  • Validate uniqueness or ranges using equals()/greaterThan():
    public function rules()
    {
        return [
            'price' => [
                'numeric',
                function ($attribute, $value, $fail) {
                    $existing = Product::where('price', '>=', $value)->first();
                    if ($existing && $existing->greaterThan($this->product)) {
                        $fail('Price must be unique.');
                    }
                },
            ],
        ];
    }
    

4. Service Layer Abstraction

  • Encapsulate Comparator logic in a service:
    class ProductService
    {
        public function getSortedProducts(array $products, string $sortBy)
        {
            $comparator = new Comparator($products);
            return match ($sortBy) {
                'price' => $comparator->sort(),
                'name' => $comparator->sort(fn ($a, $b) => strcmp($a->name, $b->name)),
                default => $products,
            };
        }
    }
    

Gotchas and Tips

Pitfalls

1. Type Safety

  • Issue: compare() may receive non-comparable objects (e.g., null, primitives).
  • Fix: Throw IncomparableException explicitly:
    public function compare($compare_with): int
    {
        if (!$compare_with instanceof self) {
            throw new IncomparableException('Can only compare with ' . self::class);
        }
        return $this->price <=> $compare_with->price;
    }
    

2. Null Handling

  • Issue: Comparator may fail if input contains null values.
  • Fix: Filter null values before passing to Comparator:
    $validItems = array_filter($items, fn ($item) => $item !== null);
    $comparator = new Comparator($validItems);
    

3. Performance with Large Datasets

  • Issue: Comparator->sort() uses PHP’s usort, which is O(n log n). For >10,000 items, consider:
    • Database sorting: Use orderBy() in Eloquent.
    • Lazy loading: Process chunks with Cursor or Collection::chunk().

4. Trait Conflicts

  • Issue: ComparisonTrait may conflict with other traits (e.g., Arrayable).
  • Fix: Use interface-only implementation or resolve conflicts with insteadof:
    trait ComparisonTrait
    {
        insteadof Arrayable {
            // Custom array conversion logic
        }
    }
    

5. Comparator State Mutability

  • Issue: Comparator stores input arrays internally. Modifying the stored array affects all operations.
  • Fix: Clone the array if immutability is needed:
    $comparator = new Comparator(array_map(fn ($item) => clone $item, $items));
    

Debugging Tips

1. Verify Comparisons

  • Test compare() logic with edge cases:
    $a = new Product(100);
    $b = new Product(100);
    $c = new Product(50);
    
    assert($a->equals($b));          // true
    assert($a->greaterThan($c));     // true
    assert($a->compare($b) === 0);   // 0 (equal)
    assert($a->compare($c) === 1);   // 1 (greater)
    

2. Check for IncomparableException

  • Wrap Comparator usage in a try-catch:
    try {
        $result = $comparator->greaterThan($invalidItem);
    } catch (
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table