Ocramius/ProxyManager: generating PHP proxy classes at runtime
🎩✨🌈 OOP Proxy wrappers/utilities - generates and manages proxies of your objects
At a glance
- What is it?
- ProxyManager is a PHP library that generates proxy classes for lazy loading, ghost objects, access interception and remote objects. It is aimed at framework and library authors, not at people looking for a reverse proxy server.
- Who is it for?
- Adopt ProxyManager if you are writing PHP code that needs generated proxies for lazy loading, ghost objects, access interception or remote objects, and you accept that the newest tagged release is 2.14.1 from 2022-03-05 while the default branch is 2.15.x. Do not adopt it if what you actually want is a reverse proxy with a web UI for routing HTTP traffic; that is a different class of tool and this repository will not do it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What ProxyManager solves, and who it is actually for
ProxyManager generates proxy classes for PHP objects. The README states the library aims to provide abstraction for generating various kinds of proxy classes, and the repository topics list aop, lazy-loading, oop and proxy. That places it in the framework-building layer of the ecosystem: dependency injection containers, ORM and persistence layers, and any code that wants to defer object construction or intercept method calls without hand-writing a subclass per class.
The audience matters because the name is ambiguous. If you arrived here from a search for a reverse proxy manager with a web interface, you are in the wrong repository. ProxyManager has no HTTP listener, no admin panel and no configuration file for routing traffic. It is a Composer package that emits PHP source for proxy classes. The people who get value from it are PHP developers writing libraries or application infrastructure, not operators configuring network entry points.
How the proxy generation mechanism works
The core idea is that you ask a factory for a proxy of a given class, and the library produces a class that extends or implements the target, then hands you an instance of it. The README example uses LazyLoadingValueHolderFactory. You pass the class name of the heavy object plus a closure that receives references to the wrapped object, the proxy, the method name, the parameters and the initializer flag. Inside the closure you construct the real object and assign it to the wrapped object reference, then set the initializer to null so later calls skip initialization, and return true to report success.
The value holder pattern is what makes the indirection work. Until the first real method call, the proxy holds nothing; on that call the initializer closure runs and the proxy delegates to the freshly built object. The examples directory in the repository shows the other shapes the library supports: examples/virtual-proxy.php, examples/ghost-object.php, examples/ghost-object-skipped-properties.php, examples/access-interceptor-scope-localizer.php, examples/smart-reference.php and examples/remote-proxy.php. Each corresponds to a different proxy type, and the README points at the docs directory for the full set rather than listing them all inline.
Because proxies are generated rather than written by hand, generated code has to be stored or regenerated. The repository carries configuration for the tooling around that work (phpunit.xml.dist, psalm.xml, phpcs.xml.dist, phpmd.xml.dist, infection.json.dist, phpbench.json, phpdox.xml.dist), which tells you the maintainers treat generated output as something to test and analyse rather than something to eyeball.
Installing ProxyManager and building a first virtual proxy
Installation goes through Composer. The README gives the command below, using the phar form of Composer; if you already have a global composer binary, the equivalent is composer require ocramius/proxy-manager.
php composer.phar require ocramius/proxy-managerAfter the command completes, the package is present in your vendor directory and autoloaded. The README then shows the shortest working use: a virtual proxy around a class named MyApp\HeavyComplexObject, created by LazyLoadingValueHolderFactory.
$factory = new \ProxyManager\Factory\LazyLoadingValueHolderFactory();
$proxy = $factory->createProxy(
\MyApp\HeavyComplexObject::class,
function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
$wrappedObject = new \MyApp\HeavyComplexObject();
$initializer = null;
return true;
}
);
$proxy->doFoo();The signature of the initializer closure is the part to read carefully. The wrapped object and the initializer flag are passed by reference, which is why the closure parameters carry the ampersands. Constructing the real object and nulling the initializer inside that closure is what converts the proxy from an empty shell into a delegate. Calling doFoo() on the proxy is what triggers the closure; before that call, no HeavyComplexObject exists. The README does not state where generated proxy files are written, so check the docs directory and the factory configuration for your chosen proxy type before you assume anything about caching or file layout.
Where ProxyManager is the wrong tool
ProxyManager proxies PHP objects. It does not proxy HTTP requests, terminate TLS, or route traffic between hosts. The related search data for this name is dominated by Nginx Proxy Manager, a separate project with a web interface and a Docker deployment; none of that behaviour exists here. If your problem is exposing a service on port 443 with a Let's Encrypt certificate, this repository cannot help and you should stop reading.
There are also PHP-specific boundaries. A proxy class has to extend or implement the type you are proxying, so final classes and final methods constrain what can be generated. The repository ships a STABILITY.md file, which is the maintainers' own statement about which APIs they consider stable; read it before you build a public API on top of a specific factory. And the access-interceptor and scope-localizer examples show that some proxy types reach into object internals, which is exactly the kind of thing that breaks when a class changes its private state shape. Generated code is still code: it needs the same tests you would write for a hand-written subclass.
ProxyManager compared with writing subclasses by hand
The obvious alternative is not another library but manual subclassing: write a class that extends the target, override the methods you care about, and defer the real work yourself. That approach is transparent, needs no code generation, and produces files your IDE understands without plugins. It also scales badly. One subclass per proxied class, per concern, means a dependency injection container that wants lazy services has to ship a lazy variant of every service, and an AOP layer has to ship an interceptor subclass for every join point.
ProxyManager moves that work to runtime generation, so a container can ask for a proxy of an arbitrary class and get one. The trade is that the generated classes are not in your source tree, your static analysis tools see the original type rather than the proxy, and debugging steps through generated code. The repository's own configuration list reflects that trade: psalm.xml, phpcs.xml.dist and phpmd.xml.dist exist because the project has to keep generated and handwritten code analysable. If your project has a handful of lazy services, hand-written subclasses are simpler. If you are building the container itself, generation is the only approach that scales.
Maintenance status, upgrade cost and the MIT licence
The repository is not archived, and the last push was on 2026-09-09. That is recent activity on the default branch, which is named 2.15.x. The release list, however, is older: 2.14.1, 2.13.1 and 2.12.1 were all tagged on 2022-03-05. So the branch has moved since the last tag, and the practical question for an adopter is which of those two facts you depend on. If you pin to a tagged release, you are on 2.14.1. If you track the branch, you are on untagged code.
The repository carries an UPGRADE.md file, which is the document to read before moving between major lines; the README does not summarise its contents. There is also a SECURITY.md for reporting vulnerabilities, and ToRussianPeople.md, which the README links at the top for readers living in Russia. The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained; that is a description of the licence text, not legal advice, and your organisation's own review decides whether it fits. The README also notes that the package is available as part of the Tidelift Subscription, with the maintainer reachable at [email protected] for private-project issues, so commercial support is a documented option rather than an assumption you have to make.
Editorial conclusion
Adopt ProxyManager if you are writing PHP code that needs generated proxies for lazy loading, ghost objects, access interception or remote objects, and you accept that the newest tagged release is 2.14.1 from 2022-03-05 while the default branch is 2.15.x. Do not adopt it if what you actually want is a reverse proxy with a web UI for routing HTTP traffic; that is a different class of tool and this repository will not do it. Before committing, verify the PHP version constraint in composer.json, read docs/ for the proxy type you intend to use, and check UPGRADE.md so you know what a future 2.15 tag would change.
Frequently asked questions
What is Ocramius/ProxyManager?
It is a PHP library that generates proxy classes for your objects. The README states it aims to provide abstraction for generating various kinds of proxy classes, and the repository topics are aop, lazy-loading, oop and proxy.
How do I install Ocramius/ProxyManager?
The README gives the Composer command php composer.phar require ocramius/proxy-manager as the suggested installation method. After that the package is autoloaded and you can use the factories under the ProxyManager namespace.
How do I use ProxyManager to lazy load an object?
The README example creates a LazyLoadingValueHolderFactory, calls createProxy() with the class name and an initializer closure, and inside that closure constructs the real object, assigns it to the by-reference wrapped object parameter and sets the initializer to null. The proxy then delegates to the real object on the first method call.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ocramius-proxymanager)