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

Lazy Objects Laravel Package

isolate/lazy-objects

A lightweight PHP package for deferring object initialization until first access. Create lazy proxies that resolve real instances on demand, helping reduce boot-time overhead and memory usage in Laravel and plain PHP apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this package as a build-time code generator, not a runtime dependency. You will not be instantiating anything from it inside request handling — you run it to emit proxy classes, then use those generated classes in your application.

Minimal steps:

  1. composer require --dev isolate/lazy-objects. Keep it in require-dev; production should only depend on the generated artifacts, not the generator itself.
  2. Read the source before the README. This is a 2015-era package (last release 2015-09-04, 2 stars, 0 dependents) with sparse documentation. Look at composer.json first for the PHP constraint, then find the generator entry point — the class that accepts a target class name and writes PHP source to disk.
  3. Verify it parses and runs on your PHP version. A package from 2015 predates PHP 7 scalar/return types, so expect --ignore-platform-reqs and possibly a small fork. Confirm generated output is syntactically valid on your runtime before building a workflow around it.
  4. Point the generator's output directory at a namespace your autoloader already knows about — a generated/ folder in your classmap, or a PSR-4 namespace you own and control.

First use case: defer an expensive constructor. Pick a class whose instantiation opens a socket, reads a large config tree, or builds a heavy object graph — a third-party SDK client, an optional integration, or an admin-only service. Generate a proxy that extends it, pass a cheap initializer closure (fn () => $container->get(ExpensiveService::class)), and the real object is built only on the first method call. Because the proxy is a subclass of the original, existing type hints and DI wiring keep working, while requests that never touch the object stop paying for it. Instrument the initializer with a counter and log once — measure the win before rolling it out.

Implementation Patterns

Initializer-closure proxy (the core pattern). The generated class extends the target, overrides public methods, and on first invocation runs your initializer, caches the real instance, and forwards. Your responsibilities are to supply a cheap closure and to verify the swap actually happens once. After the first call, assert get_class() on the wrapped instance and call two methods in sequence to confirm the second does not re-initialize.

Generate at build time, never at runtime. Add a Composer script ("post-autoload-dump": ["php bin/generate-proxies.php"]) or a CI step so proxies regenerate whenever a proxied class changes. Commit artifacts only if your deploy pipeline cannot execute PHP; otherwise generate in CI and ship them. This sidesteps filesystem-permission failures in production and keeps opcache consistent.

Apply at the container/lazy-service boundary. The cleanest day-to-day use is a DI decorator: for services tagged lazy, bind the proxy class in the container instead of the concrete class. This is conceptually the same as Symfony's lazy services or Laravel's deferred service providers, but with you owning the generated layer.

Keep the proxied surface narrow. Wrap one or two genuinely expensive dependencies behind an internal adapter interface, not ten services scattered through the codebase. If you later swap for a maintained proxy library, you replace one adapter instead of chasing Lazy* classes through the app.

Build a compatibility harness first. Before touching application code, write a throwaway test that generates a proxy for one candidate class and asserts: instantiation is deferred, one construction total, method return types match, and static analysis can resolve the class (run PHPStan on the generated output).

Gotchas and Tips

  • Final classes cannot be proxied. Inheritance-based proxies fail outright on final classes. Audit your candidate classes for final, private constructors, and readonly properties before you plan anything.
  • Constructor bypass is a feature and a trap. The proxy skips the real constructor, so any invariant the constructor establishes (validation, connection setup, property defaults) is missing until first use. Never let code inspect a proxy's own properties expecting real values.
  • Typed and readonly properties will fight you. Generated code from 2015 predates typed properties entirely. Proxying classes with uninitialized typed properties or readonly fields will throw on access. Fork and extend the generator, or exclude those classes.
  • Serialization and cloning break. serialize(), unserialize(), and clone on a proxy generally operate on the proxy, not the wrapped instance. Add __sleep/__wakeup/__clone handling in your fork or forbid proxies from crossing those boundaries.
  • Circular dependency recursion. A proxy whose initializer resolves something that transitively resolves the same proxy will loop. Guard with a resolving flag in the initializer.
  • Always re-dump the autoloader after regeneration. New generated files trigger classmap/autoload collisions on their own; bake composer dump-autoload into the generation script.
  • Bust opcache deterministically. Regenerated proxies served from a stale opcache are one of the hardest failure modes to diagnose — the class exists, the signature drifts, and you get "method called with wrong argument count" at runtime. Restart PHP-FPM or use opcache_reset() on deploy.
  • Stack traces get confusing. When something blows up inside a proxied call, the trace shows the proxy frame between your caller and the real object. Log the initializer invocation once with the target class name so profiling and debugging stay legible.
  • Interfaces only go one way. If code depends on an interface the target class implements, instanceof on the proxy works; if the type hint is the interface, PHP won't let you construct the proxy directly under that type. Type against the concrete class or an adapter interface.
  • Static analysis cannot see through it. PHPStan and Psalm resolve the proxy's own public surface. Generate stubs or exclude proxy directories to avoid a flood of false errors.
  • Prefer the native path first. Laravel's container already defers resolution through deferred providers, and Eloquent lazy loading handles relations. Justify this package only after profiling proves eager object construction is a measurable bottleneck — and then weigh it against a maintained proxy library, because you are signing up to fork and own an abandoned code generator.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo