easyframework/generics
EasyFramework Generics provides lightweight generic-style typing and reusable collection helpers for Laravel and PHP projects. It helps reduce duplication, improve clarity, and simplify common data-handling tasks with framework-friendly APIs and straightforward setup.
This package is archived (last release 2015-12-17, 0 dependents), so first decide why you are pulling it in: maintaining a legacy app that already uses it, or mining it as a reference implementation. For new code, prefer illuminate/collections, Doctrine Collections, or a small in-house base class.
Minimal steps:
composer require easyframework/generics. If Packagist resolution or the PHP constraint blocks you (likely on PHP 8), either:
require.php in composer.json, and add it as a VCS repository:
{
"repositories": [{ "type": "vcs", "url": "https://github.com/your-org/generics" }],
"require": { "easyframework/generics": "dev-main" }
}
src/ directory directly and wire up a PSR-4 autoload entry yourself.composer.json first for the autoload namespace and PHP constraint, then read src/ and tests/ — tests are the de-facto documentation for an unmaintained package.composer.lock. There will be no future patches.UserCollection that enforces User instances and gives you foreach, count(), and array access for free.$users = new UserCollection([$userA, $userB]);
foreach ($users as $user) {
// ...
}
echo count($users);
Subclass for domain collections. Extend the package's base collection and enforce the item type in the single method that adds items (add, offsetSet, or equivalent — check the source for the exact hook). This is the only place the package earns its keep over a plain array.
final class UserCollection extends Collection
{
public function add($user): void
{
if (! $user instanceof User) {
throw new InvalidArgumentException('Expected ' . User::class);
}
parent::add($user);
}
}
Prefer composition at domain boundaries. Wrap the generic collection inside your own object and expose only domain methods (activeUsers(), totalBalance()). This stops the library's API from leaking through your codebase and makes a future swap to Laravel/Doctrine collections a one-file change.
Use it as a repository return type, then convert. Hydrate Eloquent/DB rows into the domain collection in the repository, and convert back to a Laravel Collection at the controller/view boundary:
return collect($userCollection->toArray());
Don't thread the generic collection deep into Blade views or Eloquent relationships — the impedance mismatch isn't worth it.
Add adapters for iteration and JSON. If the base class doesn't implement JsonSerializable or Countable, implement them in your subclass and use toArray() as the single canonical flattening method. Test that json_encode($collection) produces an array, not an object of private properties.
Bind factories in Laravel's container. If you use collections in several services, register small factory methods (UserCollection::fromRows($rows)) and inject via the container rather than new-ing collections inline.
Testing. Unit-test your subclasses with data providers covering: valid items, wrong-type items (expect exception), empty collection, duplicate keys, and toArray/json_encode round-trips.
each(), curly-brace string offsets), lack return types, or declare php: >=5.4. Fork, bump the constraint, run PHPStan/Psalm, and add return types before adopting.EasyFramework\* packages. If vendoring manually, add the PSR-4 mapping yourself and run composer dump-autoload.jsonSerialize, __toString, and serialize() behavior. Many small collection libs expose $items as protected, which json_encode will happily ignore and serialize as {}.$items/$elements property, a type-check hook, and iterator methods. Extend and override the smallest surface; avoid overriding count()/offsetGet() unless necessary — every override is a place a future fork diverges.var_dump($collection->toArray()) is more reliable than dumping the object (private/protected state). When behavior is unclear, read tests/ — for unmaintained packages, the tests are the specification.toArray, map, filter, count). Migrating later to illuminate/collections (standalone, actively maintained) or Doctrine Collections becomes a shim instead of a rewrite.How can I help you explore Laravel packages today?