引言:为什么SOLID是高质量PHP代码的基础
每个PHP开发者迟早都会遇到这样的情况:一个小项目变成了“意大利面条式代码”。类变得臃肿,系统中一个部分的修改破坏了另一部分,测试变成了一场噩梦。正是为了解决这些问题,罗伯特·马丁(鲍勃大叔)提出了SOLID五项原则。这些原则不是抽象的理论,而是实用的工具,帮助您创建灵活、可维护且可测试的PHP代码。
在本文中,我们将逐一剖析每个SOLID原则:从理论到PHP 8.x上的实际示例。您将了解如何在日常开发中应用它们,以及应该避免哪些反模式。
1. 单一职责原则(SRP)
理论
该原则指出:一个类应该只有一个引起变化的原因。这意味着每个类应该只负责一个特定的功能或业务逻辑。
反模式(违反SRP)
<?phpclass OrderProcessor { public function process(Order $order): void { // 1. 验证订单 if (empty($order->getItems())) { throw new \\InvalidArgumentException('Order has no items'); } // 2. 保存到数据库 $db = new \\PDO('mysql:host=localhost;dbname=shop', 'user', 'pass'); $stmt = $db->prepare('INSERT INTO orders ...'); $stmt->execute([...]); // 3. 发送邮件 mail($order->getCustomerEmail(), '订单已确认', '...'); // 4. 记录日志 file_put_contents('/var/log/orders.log', 'Order processed: '.$order->getId()); }}?>这里的OrderProcessor类做了太多事情:验证、操作数据库、发送邮件、记录日志。违反SRP会导致修改邮件发送逻辑时需要修改负责订单处理的类。
遵循SRP的重构
<?phpclass OrderValidator { public function validate(Order $order): void { if (empty($order->getItems())) { throw new \\InvalidArgumentException('Order has no items'); } }}
class OrderRepository { public function save(Order $order): void { // 保存到数据库的逻辑 }}
class EmailNotifier { public function sendOrderConfirmation(Order $order): void { // 发送邮件的逻辑 }}
class Logger { public function log(string $message): void { // 日志记录 }}
class OrderProcessor { public function __construct( private OrderValidator $validator, private OrderRepository $repository, private EmailNotifier $notifier, private Logger $logger ) {} public function process(Order $order): void { $this->validator->validate($order); $this->repository->save($order); $this->notifier->sendOrderConfirmation($order); $this->logger->log('Order processed: '.$order->getId()); }}?>现在每个类都有单一的职责。修改邮件逻辑不会影响数据库操作。
2. 开闭原则(OCP)
理论
软件实体应该对扩展开放,对修改关闭。换句话说,您应该能够在不修改现有代码的情况下添加新功能。
反模式
<?phpclass PaymentProcessor { public function process(string $type, float $amount): void { if ($type === 'credit_card') { // 处理信用卡 } elseif ($type === 'paypal') { // 处理PayPal