| name | acc-solid-knowledge |
| description | SOLID principles knowledge base for PHP 8.5 projects. Provides quick reference for SRP, OCP, LSP, ISP, DIP with detection patterns, PHP examples, and antipattern identification. Use for architecture audits and code quality reviews. |
SOLID Principles Knowledge Base
Overview
SOLID is a set of five design principles for writing maintainable, extensible software.
| Principle | Name | Core Idea |
|---|
| S | Single Responsibility | One class = one reason to change |
| O | Open/Closed | Open for extension, closed for modification |
| L | Liskov Substitution | Subtypes must be substitutable for base types |
| I | Interface Segregation | Many specific interfaces > one general |
| D | Dependency Inversion | Depend on abstractions, not concretions |
Quick Detection Patterns
SRP Violations
find . -name "*.php" -exec wc -l {} \; | awk '$1 > 500 {print}'
grep -rn "class.*And[A-Z]" --include="*.php"
grep -rn "public function __construct" --include="*.php" -A 20 | grep -E "private|readonly" | wc -l
grep -rn "class.*Manager\|class.*Handler\|class.*Processor" --include="*.php"
Signs of SRP Violation:
- Class has >500 lines
- Class has >7 dependencies
- Class name contains "And", "Or", "Manager", "Handler"
- Multiple unrelated public methods
- Changes for multiple business reasons
OCP Violations
grep -rn "switch.*instanceof\|switch.*::class" --include="*.php"
grep -rn "if.*instanceof\|elseif.*instanceof" --include="*.php"
grep -rn "\[.*::class.*=>" --include="*.php"
Signs of OCP Violation:
- Switch statements on object types
- instanceof chains in conditionals
- Adding new types requires modifying existing code
- Hardcoded type-to-behavior mappings
LSP Violations
grep -rn "throw.*NotImplemented\|throw.*NotSupported" --include="*.php"
grep -rn "public function.*\{[\s]*\}" --include="*.php"
grep -rn "if.*parent::" --include="*.php"
Signs of LSP Violation:
- Child class throws NotImplementedException
- Child class has empty method overrides
- Parent type check in child class
- Preconditions strengthened in subtype
- Postconditions weakened in subtype
ISP Violations
grep -rn "interface\s" --include="*.php" -A 30 | grep -c "public function"
grep -rn "// TODO\|// not implemented\|// unused" --include="*.php"
Signs of ISP Violation:
- Interface has >5 methods
- Classes implement interfaces partially
- Unused methods return null/throw
- Interface name too generic ("Service", "Manager")
DIP Violations
grep -rn "new\s\+[A-Z]" --include="*.php" | grep -v "Exception\|DateTime\|stdClass"
grep -rn "::[a-z].*(" --include="*.php" | grep -v "self::\|static::\|parent::"
grep -rn "function.*([A-Z][a-z]*[A-Z]" --include="*.php"
Signs of DIP Violation:
new ConcreteClass() inside methods
- Static calls to concrete classes
- Type hints to concrete classes (not interfaces)
- No constructor injection
PHP 8.5 Patterns
SRP Compliant
<?php
declare(strict_types=1);
final class UserService
{
public function register(UserData $data): User { }
public function sendEmail(User $user): void { }
public function generateReport(User $user): Report { }
}
final readonly class RegisterUserHandler
{
public function __construct(
private UserRepository $users,
private EventDispatcher $events,
) {}
public function __invoke(RegisterUserCommand $command): UserId
{
$user = User::(->email, ->password);
->users->();
->events->(->());
->id;
}
}
OCP Compliant
<?php
declare(strict_types=1);
final class PaymentProcessor
{
public function process(Payment $payment): void
{
match ($payment->type) {
'card' => $this->processCard($payment),
'paypal' => $this->processPaypal($payment),
};
}
}
interface PaymentGateway
{
public function supports(Payment $payment): bool;
public function process(Payment $payment): PaymentResult;
}
final readonly class PaymentProcessor
{
public () {}
{
(->gateways ) {
(->()) {
->();
}
}
(->type);
}
}
LSP Compliant
<?php
declare(strict_types=1);
abstract class Bird
{
abstract public function fly(): void;
}
final class Penguin extends Bird
{
public function fly(): void
{
throw new CannotFlyException();
}
}
interface Bird
{
public function move(): void;
}
interface FlyingBird extends Bird
{
public function fly(): void;
}
final readonly class Penguin implements Bird
{
public {
->();
}
{ }
}
{
{
->();
}
{ }
}
ISP Compliant
<?php
declare(strict_types=1);
interface UserRepository
{
public function find(UserId $id): ?User;
public function findByEmail(Email $email): ?User;
public function save(User $user): void;
public function delete(User $user): void;
public function findAll(): array;
public function count(): int;
public function export(): string;
public function import(string $data): void;
}
{
;
;
}
{
;
;
}
{
;
;
}
{}
DIP Compliant
<?php
declare(strict_types=1);
final class OrderService
{
public function process(Order $order): void
{
$mailer = new SmtpMailer();
$logger = Logger::getInstance();
$validator = new OrderValidator();
}
}
final readonly class OrderService
{
public function __construct(
private OrderRepository $orders,
private Mailer $mailer,
private LoggerInterface $logger,
private OrderValidator $validator,
) {}
public function process(Order $order):
{
->validator->();
->orders->();
->mailer->( ());
->logger->(, [ => ->id->value]);
}
}
SOLID & DDD Integration
| SOLID | DDD Application |
|---|
| SRP | Aggregates have single consistency boundary |
| OCP | Domain Events enable extension without modification |
| LSP | Value Objects are substitutable (same type = same behavior) |
| ISP | Repository interfaces segregated (Reader/Writer) |
| DIP | Domain depends on Repository interfaces, not implementations |
SOLID & Clean Architecture
| Layer | SOLID Focus |
|---|
| Domain | SRP (Entities), LSP (Value Objects), ISP (Repository interfaces) |
| Application | SRP (Use Cases), DIP (Port interfaces) |
| Infrastructure | OCP (Adapters), DIP (Implements ports) |
| Presentation | SRP (Controllers), ISP (API contracts) |
Severity Levels
| Level | Description | Example |
|---|
| CRITICAL | Fundamental violation affecting entire system | God class, no DI |
| WARNING | Localized violation, should be fixed | instanceof chains |
| INFO | Minor issue, consider refactoring | Interface with 6 methods |
References
See detailed documentation in references/:
srp-patterns.md - Single Responsibility patterns
ocp-patterns.md - Open/Closed patterns
lsp-patterns.md - Liskov Substitution patterns
isp-patterns.md - Interface Segregation patterns
dip-patterns.md - Dependency Inversion patterns
antipatterns.md - Common SOLID violations
See assets/report-template.md for audit report format.