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

Laravel Any Laravel Package

nunomaduro/laravel-any

Nuno Maduro's tiny Laravel helper that resolves any class through the service container, automatically injecting its dependencies so you can instantiate objects with zero boilerplate.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Effectively zero architectural surface: the package ships one Collection::macro('any', ...) registered by a service provider, with no config file, no published assets, no events, no driver, no extension points. It neither constrains nor participates in the domain model — it is a syntax preference expressed as a manifest entry. On Laravel 5.5–8 it composes cleanly with Eloquent collections (inherited via Illuminate\Database\Eloquent\Collection) and slots into guard clauses, policies, form requests, and test assertions. On Laravel 9+ it is a second implementation of a native method, competing on provider registration order.

Integration feasibility. Trivial mechanically — composer require, auto-discovery, done in under a minute. The TPM-relevant cost is not integration; it is the lifetime cost of owning a dependency that does roughly six lines of work. That asymmetry is the whole evaluation.

Technical risk. Ranked by likelihood × impact:

  1. Guaranteed obsolescence. Laravel 9+ ships native Collection::any(); PHP 8.4 adds array_any(). Adoption creates a removal ticket at the next framework or language upgrade — a cost booked against the platform roadmap, not the feature team.
  2. Silent comparison semantics. If the macro uses == where call sites assume ===, boolean drift appears with no type-checker or review signal (collect(['0'])->any(fn ($v) => $v == 0) is true). This is the one genuine defect class and must be pinned by test before first merge.
  3. Registration timing. The classic production-only failure: macro works in controllers (provider booted via discovery) but a queue worker, early-booting Artisan command, or stale config:cache throws Method Illuminate\Support\Collection::any does not exist. Also affects Octane and long-running workers if registration ever becomes conditional.
  4. Query-count trap. any() is in-memory only. $tenant->subscriptions()->any(...) runs SELECT * then iterates in PHP. Existence questions belong in SQL as ->where(...)->exists(); the ergonomic name invites the wrong call.
  5. Supply-chain signals. 38 stars, 0 dependents, 0.25 composite score, single maintainer, no stated support SLA. Under any written dependency-governance gate, this fails adoption-signal criteria — which is precisely why it is a safe package to use as the precedent-setting example.
  6. Documentation/identity mismatch. The stated description ("work with any Laravel version from a single project") does not match the shipped capability (Collection::any()). Before any decision, confirm we are evaluating the right artefact and the right README — a package whose stated purpose and actual surface diverge is an evaluation blocker, not a footnote.

Key questions.

  • What is the actual distribution of Laravel versions across the fleet, and does method_exists(Illuminate\Support\Collection::class, 'any') return false on every target?
  • How many call sites would realistically use ->any()? Below ~20, the dependency never amortises its own review, audit, and upgrade cost.
  • Is ->any() an explicit, written team standard, or one engineer's preference? If the latter, this is a style-guide entry, not an architecture decision.
  • Does the macro use === or ==, and does the predicate accept key/value pairs?
  • Who owns the removal ticket, and on what date? If no name can be attached, do not install.
  • Does contains(callable) — identical semantics, including short-circuiting, zero dependencies — already satisfy the readability goal?

Integration Approach

Stack fit. Appropriate only where the framework lacks native any() (broadly pre-Laravel 9) and the team has formally standardised on the ->any() idiom. Where either condition fails, the correct answer is either native Collection::any(), contains($callback), or a first-party macro.

Recommended path: build in-house. A single Collection::macro('any', ...) in an internal CollectionMacrosServiceProvider plus a style-guide note delivers identical ergonomics, full test ownership, no manifest entry, no audit surface, and no removal ticket. Engineering owns how; the PM owns whether the idiom is standardised. Splitting it that way keeps a style preference from quietly becoming an architectural dependency.

If the package is adopted anyway — prototype, internal tool, timeboxed spike, or workshop material — sequence it as follows:

  1. Verify the need. php artisan tinker --execute="var_dump(method_exists(Illuminate\Support\Collection::class, 'any'));" and composer show laravel/framework. If true, stop.
  2. Read the provider before the first merge and answer the two questions that determine semantics: === vs ==, and key/value support.
  3. Count intended call sites and record the number in the ADR. It is the baseline for the build-vs-buy decision.
  4. Wrap at the boundary so migration to native any() / array_any() is a one-file change rather than a grep-and-rewrite:
    final class Collections
    {
        public static function any(iterable $items, callable $test): bool
        {
            return collect($items)->any($test);
        }
    }
    
  5. Consolidate macro registration in one provider — scattered Collection::macro() calls produce silent ordering bugs.
  6. Lock semantics with a unit test asserting strict comparison and empty-collection behaviour, so a future version bump cannot change results unnoticed.
  7. Record the decision: ADR entry, composer audit in CI, and a removal ticket filed the day of install, owned by name, tied to the Laravel 9 / PHP 8.4 upgrade milestone.

Compatibility notes. Auto-discovery covers Laravel 5.5+; there is nothing to publish or configure. Rebuild config:cache after installation, and plan a worker restart as part of the deploy if any long-running process could have booted before the provider was registered. On upgrade to Laravel 9+, remove the package — native any() is a drop-in and the two must not coexist.

Operational Impact

Maintenance. Near-zero code maintenance, non-zero governance overhead: manifest entry, audit cadence, upgrade coordination, and a scheduled removal. Net cost is negative relative to six lines of first-party code — we pay review and lifecycle attention for a capability we could own outright. Every subsequent dependency request can be measured against this baseline: does it do more than six lines of work, does it carry maintenance we would otherwise own, does it have a future past the next framework upgrade?

Support. Single maintainer, no visible security-contact or issue-response commitment, no dependents to surface breakage early. Bus factor is the entire risk. Acceptable for a spike or internal tool; not acceptable for a production-critical path under a strict supply-chain review.

Scaling. No runtime performance argument either way: any() is O(1) best case and O(n) worst, identical to contains(). Short-circuiting is the guarantee, not an optimisation. The real scaling exposure is misuse — in-memory evaluation over an eager-loaded relation where a SQL existence check was the correct primitive. Call this out in the style guide, not just the PR review.

Failure modes to instrument for.

  • BadMethodCallException: Method Collection::any does not exist in queue workers, early-booting Artisan commands, or after a stale config:cache — the production-only failure that never appears in staging.
  • Silent boolean drift from loose comparison — invisible to review and static analysis; only a pinned unit test catches it.
  • Registration-order shadowing on Laravel 9+ once both implementations exist.
  • Empty-collection semantics: any() returns false on empty, so any(fn ($i) => $i->isInvalid()) is not the negation of every(fn ($i) => $i->isValid()). Teams conflate these; document which question is being asked.
  • Octane and long-running workers serving stale boot state if registration is ever env-gated or feature-flagged.

Ramp-up. Minutes for engineers already fluent in collections; the ergonomics are self-evident. The ramp-up that actually matters is organisational: this package is the ideal low-stakes worked example for socialising a written "no unmaintained micro-packages in production" gate and a minimum adoption bar — adoption signals, maintenance cadence, security-contact availability, licence fit, and overlap with native framework capability. The principle lands far better when the example is trivially replaceable.

Positioning. Internal tooling, test assertions, admin utilities, and engineer onboarding — never a customer-facing roadmap item. Low effort, low differentiation, zero customer impact. Useful as a teaching artefact for distinguishing an ergonomics preference from a product decision, and as the reference case for build-vs-buy calibration.

Default recommendation: do not adopt. Build the macro in-house or use contains(); the dependency does not amortise its own review, audit, and upgrade cost, and it is guaranteed dead weight at the next framework or language upgrade.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource