hoa/iterator
Hoa\Iterator is a PHP library offering a comprehensive collection of iterator classes and helpers, including filters, maps, limits, aggregates, and recursive traversals, for composing elegant, reusable iteration logic over arrays and other traversable data.
What it is. hoa/iterator is the Hoa Project’s iterator toolkit: a set of Iterator/IteratorAggregate implementations (buffer, callback filter, CSV, directory, limit, map, regular-expression, split, token, infinite/repeater, etc.) plus glue for composing them. It is framework-agnostic PHP — there is no Laravel service provider, facade, config, or container binding. Any Laravel usage is as a leaf dependency inside application or domain code, not as a framework extension.
Architecture fit. Fits only where the requirement is genuinely lazy, pull-based traversal over a stream or unbounded source (large CSV imports, directory walks, token scanning) and where the team wants pre-built combinators rather than writing generators. In a modern Laravel codebase, LazyCollection, native generators, and SPL (SplFileObject, LimitIterator, CallbackFilterIterator, RegexIterator) cover the same ground with zero dependency cost. Fit is therefore narrow — a handful of legacy or specialized call sites, not an architectural layer.
Integration feasibility. Mechanically easy: Composer install, PSR-4 autoload, no native extensions, no runtime services. The friction is transitive — it drags in sibling Hoa packages (consistency, exception, and the stream stack), each carrying the same abandonment profile. There is no Laravel package discovery, so nothing auto-wires; you instantiate directly. BSD-3-Clause licensing is permissive and low-risk.
Technical risk — high, and mostly non-technical.
Xcallable, custom exception hierarchy, stream wrappers) does not map cleanly onto SPL contracts; code that expects \RuntimeException or standard Iterator semantics may get surprises.Key questions to answer before adopting.
LazyCollection/generators/SPL cannot express in under ~50 lines? If the answer is "none," stop here.Stack fit. Treat it as a utility leaf, never as a public contract. Do not leak Hoa\Iterator\* types across module or service boundaries; convert to \Iterator, \Generator, or LazyCollection at the boundary. Laravel’s container, queues, and Eloquent have no opinion about it, which is both the appeal and the reason it adds nothing framework-native.
Migration path (preferred: replace, don’t integrate).
LazyCollection::make() + Generators + SplFileObject; measure LOC delta. In most cases the native rewrite is smaller than the adapter.App\Support\Iteration\RowStream) with a Hoa-backed implementation hidden inside.Hoa\Iterator imports.If adoption is unavoidable.
composer.json; commit the lockfile; add composer audit to CI.App\Vendor\HoaIterator) so the archived upstream cannot be silently swapped and so we can patch.new scattered through controllers.Compatibility. Run the full test suite on the oldest and newest PHP in the support matrix; assert zero deprecations under E_ALL. Verify autoload does not collide with other Hoa packages already present. Confirm exception types thrown by stream-backed iterators are catchable as standard SPL exceptions where callers expect it.
Sequencing. Prove compatibility → spike native alternative → decide replace vs. wrap → if wrap, add adapter + tests + ADR → migrate call sites opportunistically → set a review date (12 months) with an explicit sunset criterion.
Maintenance. Effectively ours. No upstream releases, no security advisories, no PR merge path — archived means issues and PRs are closed loops. Dependency scanners will flag it as abandoned, and the transitive Hoa packages compound that. Budget a small standing allowance for PHP-upgrade remediation, and expect it to surface during every major runtime bump.
Support. No vendor, no community channel with throughput. Support is internal tribal knowledge held by whoever wrote the adapter. Document the wrapped behaviors in a runbook, including any Hoa-specific semantics (non-rewindable iterators, buffering, Xcallable invocation rules), or the knowledge leaves with the author.
Scaling. This is the one genuine upside: generator-style traversal keeps memory flat where an array-based implementation would blow up on large files or result sets. But not all Hoa iterators are lazy — buffering and serializing variants deliberately materialize state, which can silently invert the memory profile. Benchmark the specific iterators in use under production-shaped inputs (row counts, file sizes, queue concurrency), not the library as a whole. CPU cost of userland iterator chains is modestly higher than an equivalent foreach/generator loop; measure before assuming it matters.
Failure modes to plan for.
Ramp-up. Low-to-moderate for a mid-level PHP developer: iterator and SPL concepts transfer directly, so the core API reads familiar within a day. The friction is Hoa’s idiosyncratic conventions (Consistency\Xcallable, custom exception hierarchy, stream wrappers), which are poorly documented and unmaintained — expect additional time for anyone touching stream-backed or tokenizing iterators. Net estimate: roughly half a day for basic combinators, one to two days to be safe with the stream-dependent classes.
Bottom line. The library is technically competent but stranded: archived, single-release-since-2017, zero dependents, and superseded in nearly every use case by native PHP and LazyCollection. The rational TPM position is replace, don’t integrate — fund the short native rewrite, and only wrap it if a specific iterator proves genuinely costly to reproduce, in which case fork it, pin it, document it, and put a removal ticket on the board with a date.
How can I help you explore Laravel packages today?