SOLID Principles in PHP: A Complete Guide with Code Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why SOLID is the Foundation of Quality PHP Code

\n\n

Every PHP developer sooner or later faces the problem of "spaghetti code": classes become overloaded, changes in one place break the entire application, and testing turns into a nightmare. The solution to this problem is the SOLID principles. Developed by Robert Martin (Uncle Bob), these five principles of object-oriented programming help create flexible, maintainable, and scalable code.

\n\n

In this article, we will break down each of the five SOLID principles with practical PHP examples. You will learn how to apply them in real projects and see the difference between "bad" and "good" code. The material is suitable for both beginners and experienced developers looking to systematize their knowledge.

\n\n

1. Single Responsibility Principle (SRP)

\n\n

Essence of the Principle

\n

A class should have only one reason to change. This means that each module or class is responsible for one specific task.

\n\n

Bad Example (SRP Violation)

\n
<?php\nclass Report {\n    public function generateReport($data) {\n        // Generating report data\n        $report = "Report: " . json_encode($data);\n\n        // Saving to file\n        file_put_contents('report.txt', $report);\n\n        // Sending via email\n        mail('admin@example.com', 'New Report', $report);\n\n        return $report;\n    }\n}\n?>
\n

Here the Report class does three different things: generates a report, saves it, and sends it. Changing the email sending logic will break the report generation.

\n\n

Good Example (SRP Compliance)

\n
<?php\nclass ReportGenerator {\n    public function generate(array $data): string {\n        return "Report: " . json_encode($data);\n    }\n}\n\nclass ReportSaver {\n    public function save(string $report, string $filename): void {\n        file_put_contents($filename, $report);\n    }\n}\n\nclass ReportMailer {\n    public function send(string $report, string $email): void {\n        mail($email, 'New Report', $report);\n    }\n}\n\n// Usage\n$generator = new ReportGenerator();\n$report = $generator->generate($data);\n\n$saver = new ReportSaver();\n$saver->save($report, 'report.txt');\n\n$mailer = new ReportMailer();\n$mailer->send($report, 'admin@example.com');\n?>
\n

Now each class has a single responsibility, and changing the saving method will not affect email sending.

\n\n

2. Open/Closed Principle (OCP)

\n\n

Essence of the Principle

\n

Software entities should be open for extension but closed for modification. In other words, you should be able to add new functionality without changing existing code.

\n\n

Bad Example (OCP Violation)

\n
<?php\nclass PaymentProcessor {\n    public function process($type, $amount) {\n        if ($type === 'credit_card') {\n            // Process credit card\n        } elseif ($type === 'paypal') {\n            // Process PayPal\n        } elseif ($type === 'bitcoin') {\n            // Process Bitcoin\n        }\n        // Each new payment type requires changing this method!\n    }\n}\n?>
\n\n

Good Example (OCP Compliance)

\n
<?php\ninterface PaymentMethod {\n    public function process(float $amount): bool;\n}\n\nclass CreditCardPayment implements PaymentMethod {\n    public function process(float $amount): bool {\n        // Credit card payment logic\n        echo "Card payment: $amount\\n";\n        return true;\n    }\n}\n\nclass PayPalPayment implements PaymentMethod {\n    public function process(float $amount): bool {\n        // PayPal payment logic\n        echo "PayPal payment: $amount\\n";\n        return true;\n    }\n}\n\nclass BitcoinPayment implements PaymentMethod {\n    public function process(float $amount): b                

Blogs

Book Recommendations