Open/Closed Principle — PHP Examples
Also Known As
TL;DR
Explanation
The Open/Closed Principle (OCP, the O in SOLID) means adding a new feature should require writing new code, not editing existing code and potentially breaking it. In PHP, OCP is achieved through: interface-based polymorphism (new payment gateways implement PaymentGatewayInterface without changing the PaymentService), strategy pattern (swap sorting algorithms by injecting a different Sorter), decorator pattern (add logging or caching by wrapping an existing service), and event/hook systems (fire an OrderPlaced event; new behaviour is added by registering listeners). The smell indicating OCP violation is a switch/match on a type tag that must be extended every time a new type is added — replace with polymorphism. Avoid premature OCP abstraction — only apply it where extension points are genuinely needed.
Common Misconception
Why It Matters
Common Mistakes
- Switch statements on type that grow with every new type — use polymorphism instead.
- Configuration-driven behaviour that requires code changes to add new configurations — move to data.
- Not designing extension points in libraries — callers need to monkey-patch instead of extending cleanly.
- Misapplying OCP to stable, simple code — premature abstraction for extension is worse than a small switch.
Code Examples
// Must edit this switch every time a new format is added
function export(Report $r, string $format): string {
return match($format) {
'csv' => exportCsv($r),
'pdf' => exportPdf($r),
};
}
interface ReportExporter {
public function export(Report $r): string;
}
// New formats: implement ReportExporter, register — no existing code changes