Introduction: Why SOLID is the Foundation of Quality PHP Code
\n\nEvery 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\nIn 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\n1. Single Responsibility Principle (SRP)
\n\nEssence of the Principle
\nA class should have only one reason to change. This means that each module or class is responsible for one specific task.
\n\nBad 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?>\nHere 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.
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?>\nNow each class has a single responsibility, and changing the saving method will not affect email sending.
\n\n2. Open/Closed Principle (OCP)
\n\nEssence of the Principle
\nSoftware 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\nBad 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\nGood 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