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

Proxy Laravel Package

yiisoft/proxy

yiisoft/proxy provides lightweight proxy objects for PHP that defer instantiation until first use, enabling lazy service loading and cleaner dependency injection without changing your application code. Part of the Yii 3 ecosystem.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What we are evaluating. yiisoft/proxy is the Yii3 component for building runtime proxy objects — it generates a subclass of a target class whose methods delegate to a wrapped instance. It is a plumbing library, not an application feature: it exists so a service can be type-compatible with a concrete class or interface while its real construction is deferred or intercepted. It is framework-agnostic in design (PSR-friendly, no Yii runtime coupling implied) but it is maintained by the Yii core team for Yii's DI/definitions use cases.

Architecture fit. Moderate-to-weak for a Laravel codebase as a primary architectural tool, strong as a surgical utility.

  • Laravel's container already resolves lazily; the common reasons a Laravel team reaches for a proxy library are (a) deferring construction of expensive side-effectful clients that are constructor-injected as concrete classes, (b) decorating a final-ish or type-strict collaborator without changing call sites, (c) intercepting calls for instrumentation. Cases (a) and (c) are usually better served by container bindings, ContextualAttribute, or a thin decorator. Case (b) is where a runtime proxy genuinely earns its keep.
  • It does not fight Laravel's architecture — it sits underneath it — but it also has no Laravel affordances: no service provider, no config, no facade. Everything is manual wiring, which is fine but signals "you own this."
  • Highest-fit targets: legacy concrete-class dependencies you cannot refactor, third-party SDK clients with heavy constructors, and test doubles where final blocks conventional mocking.

Integration feasibility. Straightforward technically. composer require yiisoft/proxy, bind the proxy manager as a singleton in a service provider, point generated-code output at a writable path (storage/framework/proxies or a build-time directory). No Laravel version constraints are implied by a general-purpose proxy generator, so installation risk is low. The real integration work is policy work: deciding where proxies are permitted, because unconstrained use makes the object graph opaque.

Technical risk (ranked).

  1. Runtime code generation is the dominant risk. Any library that emits PHP subclasses from reflection is coupled to PHP's type system and will need updates for new syntax (readonly classes, property hooks, asymmetric visibility, DNF types). A PHP minor upgrade in our stack can break generation in ways that surface at boot, not at test time.
  2. Dependency/ecosystem concentration. 22 stars, single-vendor stewardship, low external adoption. There is no crowd-sourced battle-testing outside Yii3. The recent release date (2026-04-02) is a positive maintenance signal but does not offset the bus-factor concern.
  3. Debuggability tax. Proxied objects have a different get_class(), appear oddly in stack traces, confuse dd()/var_dump, IDE navigation, and static analysis. Doctrine and Laravel internals occasionally make decisions on concrete class identity.
  4. Filesystem and deploy coupling. Generated classes must be writable at runtime or pre-generated at build. Read-only container filesystems, OPcache staleness, and multi-worker races are all live failure modes.
  5. Semantic drift. Proxies forwarding calls must faithfully reproduce return types, static returns, by-reference parameters, and magic methods. Gaps here show up as subtle bugs, not loud failures.
  6. Licensing is a non-issue: BSD-3-Clause is permissive; we only owe attribution retention.

Key questions to close in the spike.

  • What is the concrete use case, and does Laravel's container or a hand-written decorator already solve it? If we cannot name a case that fails both alternatives, we should not adopt.
  • Which PHP versions must we support, and does the generator handle every type construct in the target classes today?
  • Does it correctly proxy final methods, static returns, by-reference params, __call, __get, and readonly properties?
  • Can proxies be pre-generated at deploy time (build step) rather than lazily at request time?
  • How does it interact with composer dump-autoload --classmap-authoritative and OPcache preloading?
  • What is the package's versioning/deprecation policy, and how quickly did it absorb the last two PHP minor releases?
  • Is serialization of a proxied object required anywhere in our code (queues, cache)? Proxies typically do not serialize cleanly.

Integration Approach

Stack fit. Compatible in principle with any Laravel 10/11/12 application on a supported PHP 8.x. It brings no HTTP, container, or config opinions, so it will not collide with Laravel's kernel. Two friction points to design around: generated classes live outside Composer's autoload map (load them via an explicit require or a registered autoloader scoped to the proxy directory), and the proxy manager is stateful enough that it should be a singleton, not resolved per call.

Migration path. Treat this as an additive capability, not a migration. Nothing existing changes.

  1. Spike (1–2 days). One isolated, high-pain concrete dependency — ideally a third-party client with a slow constructor — proxied end-to-end in a branch. Measure boot time / memory delta, confirm the proxied object is indistinguishable under instanceof and interface type hints.
  2. Wrapper (1 day). A small ProxyServiceProvider plus an internal LazyProxy helper that centralizes the manager instance, the output directory, and a config flag. Application code must never touch yiisoft/proxy types directly; it should call our helper. This is the single most important decision — it makes the dependency replaceable.
  3. Policy + guardrails (1 day). A short ADR stating permitted use cases (deferred construction of expensive concrete-class collaborators; test doubles for final classes), plus a code-review rule that proxies may not wrap domain entities, Eloquent models, or anything that is serialized.
  4. Contract tests (1–2 days). Table-driven tests asserting proxied and real instances are behaviorally identical for the methods we rely on, run across the PHP versions in our CI matrix.
  5. Rollback. Because usage is behind our own helper, rollback is a config flip plus removal of a handful of call sites. Budget is under a day.

Compatibility checks before committing.

  • composer why-not against our pinned psr/* and PHP constraint to confirm no transitive conflict.
  • CI matrix: every PHP minor we deploy, plus one ahead, to catch type-syntax regressions early.
  • Verify the build pipeline's read-only filesystem story: proxies generated at image build, not at runtime.
  • Confirm composer install --classmap-authoritative in production does not shadow the proxy autoloader.

Sequencing. Spike → wrapper + ADR → contract tests → one production call site → observe for a release cycle → only then consider a second use case. Do not adopt this library speculatively; it has no value until a specific class needs it.

Alternatives to weigh at the decision point. Laravel container closures / bind with a deferred resolver (zero dependency), a hand-written decorator implementing the same interface (zero dependency, more code), or friendsofphp/proxy-manager-lts (far larger installed base, more maturity, heavier footprint). If the spike shows the Yii package's API surface is thin enough to reimplement in ~100 lines, that may be the cheaper long-term answer than taking on a 22-star dependency for a plumbing concern.

Operational Impact

Maintenance. Low ongoing code cost, non-trivial watcher cost. The library itself will not require frequent changes; what requires attention is PHP releases. Assign ownership of "PHP upgrade readiness" to the platform team and add the proxy generation step to the upgrade checklist. Pin the version explicitly (no floating constraint) and review the changelog on every bump. The BSD-3-Clause attribution must be carried into any distributed artifact.

Support. No commercial support, no Laravel community footprint, no Stack Overflow corpus. Escalation path is GitHub issues with Yii maintainers — a responsive but small team, and our use case (Laravel, not Yii DI) is not their design center. Expect to debug generation failures ourselves by reading generated output; that is a reasonable competency for a senior PHP engineer but should be named as an accepted cost, not discovered later.

Scaling characteristics.

  • Generation cost is per unique proxied class, not per request — negligible after warm-up, provided proxies are cached.
  • Under php-fpm, lazy generation on first request per worker is acceptable but wasteful; prefer build-time generation.
  • Under Octane/Swoole, generate at boot or build, never mid-request: concurrent workers writing the same generated file to a shared volume is a real race, and OPcache will not pick up a file rewritten under a live worker.
  • Memory: each generated class consumes OPcache space permanently. With a large proxied surface this becomes measurable; keep the proxied set small by policy.

Failure modes to plan for (with detection).

  • Generation failure (final class, unproxyable signature, exotic type) → hard error at resolution time. Detect in CI via the contract test suite, not in production.
  • Filesystem failure (read-only volume, permissions, disk full) → boot-time fatal. Mitigate by generating at build and treating the proxy directory as an artifact.
  • Stale proxy after a class signature change → method-not-found or wrong-arity errors that survive a normal deploy if the directory is cached. Mitigate with cache-busting keyed to a hash of source signatures.
  • Serialization failure when a proxied object reaches a queue or cache → silent data corruption risk. Mitigate with the "no proxies on serialized objects" policy plus an assertion in the model/serialization layer.
  • Identity surprises (get_class, strict === comparisons, container re-resolution returning a proxy where a concrete instance was expected) → integration-level bugs. Mitigate with contract tests and a grep-able naming convention for proxied bindings.
  • PHP upgrade breakage → catch with the CI matrix ahead of the upgrade, not after.

Ramp-up. A competent Laravel engineer is productive with the API in half a day; the real learning curve is debugging generated code and knowing when a proxy is the wrong tool — call it 2–3 days to fluency. Document the ADR, the helper, and one worked example in the team handbook. Onboarding cost is small but the concept is unusual enough that it will generate review questions on every PR; the policy document is what keeps that from becoming friction.

Bottom line. Technically sound, cheap to integrate, and genuinely useful for a narrow class of problems — but it is a low-adoption, single-vendor, code-generation dependency, and code generation is the single most PHP-version-fragile technique available. Approve it only behind an internal wrapper, only for named use cases, only with build-time generation and a PHP-version CI matrix. If the spike cannot produce a case that Laravel's container and a plain decorator both fail, decline and revisit when one appears.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource