Proxy Pattern
Also Known As
proxy
virtual proxy
protection proxy
caching proxy
TL;DR
Provides a surrogate object that controls access to another object, adding indirection for lazy loading, caching, logging, or access control.
Explanation
The Proxy pattern places an intermediary in front of a real object, implementing the same interface. Types: Virtual Proxy (defers expensive object creation until needed — lazy loading), Caching Proxy (caches results of operations on the real object), Protection Proxy (enforces access control), and Remote Proxy (represents an object in a different process or server). In PHP, Doctrine ORM uses virtual proxies for lazy-loaded entities. The Proxy differs from Decorator in intent: Decorator adds behaviour, Proxy controls access. PHP's magic methods (__get, __call) enable dynamic proxy creation.
Common Misconception
✗ Proxy and decorator patterns are interchangeable. Proxies control access to an object (lazy loading, caching, access control) while decorators add behaviour. A proxy typically has a reference to the real subject from construction; a decorator receives it via injection.
Why It Matters
A proxy controls access to another object — it can add caching, logging, access control, or lazy initialisation transparently without changing the real object or its callers.
Common Mistakes
- Not implementing the same interface as the real subject — callers must change to use the proxy.
- Proxy that adds logic the real object should have — the proxy should be transparent infrastructure, not business logic.
- Virtual proxies that initialise the real object eagerly — defeating the lazy loading purpose.
- Confusing proxy (same interface, controlled access) with decorator (same interface, added behaviour) — they serve different purposes.
Code Examples
✗ Vulnerable
// Direct access — no caching, no access control:
class ReportService {
public function getExpensiveReport(int $id): Report {
return $this->db->runHeavyQuery($id); // Called every time
}
}
// A CachingReportProxy would intercept and cache without changing ReportService
✓ Fixed
interface Image {
public function render(): string;
}
class RealImage implements Image {
public function __construct(private string $path) {
$this->loadFromDisk(); // expensive
}
public function render(): string { return "<img src='{$this->path}'>"; }
}
// Lazy-loading proxy — defers expensive load until render() is first called
class LazyImage implements Image {
private ?RealImage $real = null;
public function __construct(private string $path) {}
public function render(): string {
$this->real ??= new RealImage($this->path);
return $this->real->render();
}
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
18
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
Amazonbot 7
Google 3
Perplexity 2
ChatGPT 2
Ahrefs 1
Bing 1
How they use it
crawler 14
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Medium
⚡ Quick Fix
Use a proxy when you need to control access to an object (access control, logging, lazy initialisation) without changing its interface
📦 Applies To
PHP 5.0+
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Access control or lazy loading logic mixed directly into the real object instead of a transparent proxy
Auto-detectable:
✗ No
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: Class
Tests: Update