Weave Code
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor