Katmanlı Mimari: Düzenli ve Sürdürülebilir PHP Projeleri
Orta ölçekli bir PHP projesinde katmanlı mimari kullanmak, kodun okunabilirliğini, test edilebilirliğini ve bakımını kolaylaştırır. Bu yapıyı controller, service, repository, domain ve infrastructure katmanlarına ayırarak, her katmanın sorumluluğunu netleştirelim. Ayrıca paylaşımlı hosting uyumluluğunu da göz önünde bulunduralım.
1. Klasör Yapısı ve Katmanlar
Örnek bir proje dizini şöyle olabilir:
project/
├── src/
│ ├── Controller/
│ │ └── UserController.php
│ ├── Service/
│ │ └── UserService.php
│ ├── Repository/
│ │ └── UserRepository.php
│ ├── Domain/
│ │ └── Entity/
│ │ └── User.php
│ └── Infrastructure/
│ └── Database/
│ └── PdoAdapter.php
├── public/
│ └── index.php
└── config/
└── database.php
2. Katmanların Sorumlulukları
Her katman belirli bir sorumluluğa sahiptir:
| Katman | Sorumluluk |
|---|---|
| Controller | HTTP isteklerini alır, yanıt döner; iş mantığını Service'e yönlendirir. |
| Service | İş mantığını içerir; birden fazla Repository veya Domain nesnesini koordine eder. |
| Repository | Veri erişimini soyutlar; Domain entity'leri üzerinde CRUD işlemleri yapar. |
| Domain | İş kurallarını ve entity'leri barındırır; framework bağımsızdır. |
| Infrastructure | Teknik detayları (veritabanı bağlantısı, dosya sistemi) yönetir. |
Controller: HTTP isteğini alır, Service'i çağırır.
class UserController {
public function __construct(private UserService $userService) {}
public function show(int $id): array {
return $this->userService->getUserById($id);
}
}
Service: İş mantığını yürütür, Repository ve Domain'i kullanır.
class UserService {
public function __construct(private UserRepository $userRepo) {}
public function getUserById(int $id): ?User {
return $this->userRepo->find($id);
}
}
Repository: Veritabanı işlemlerini soyutlar.
class UserRepository {
public function __construct(private PdoAdapter $pdo) {}
public function find(int $id): ?User {
$row = $this->pdo->query('SELECT * FROM users WHERE id = ?', [$id]);
return $row ? new User($row['id'], $row['name']) : null;
}
}
Domain Entity: İş kurallarını içerir.
class User {
public function __construct(
private int $id,
private string $name
) {}
public function rename(string $newName): void {
if (strlen($newName) < 2) {
throw new \InvalidArgumentException('Name too short');
}
$this->name = $newName;
}
}
Infrastructure: Teknik detayları yönetir, örneğin PDO adaptörü.
class PdoAdapter {
private \PDO $pdo;
public function __construct(string $dsn, string $user, string $pass) {
$this->pdo = new \PDO($dsn, $user, $pass);
}
public function query(string $sql, array $params = []): ?array {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetch(\PDO::FETCH_ASSOC) ?: null;
}
}
4. Paylaşımlı Hosting Uyumluluğu
Paylaşımlı hostingler genellikle PHP 7.4 veya 8.x destekler, ancak kısıtlamaları vardır:
[*]Composer kullanımı: Çoğu paylaşımlı hosting Composer'ı destekler, ancak otomatik yükleyiciyi doğru yapılandırmak gerekir.
[*]Dosya izinleri: Katmanlı yapı özel bir izin gerektirmez, ancak config dosyalarının okunabilir olduğundan emin olun.
[*]Performans: Çok sayıda katman, özellikle küçük projelerde ek yük oluşturabilir. Ancak orta ölçekli projeler için bu genellikle kabul edilebilir.
[*]Veritabanı: PDO ve MySQLi yaygın desteklenir; Infrastructure katmanınızı buna göre tasarlayın.
[*]Önbellekleme: Paylaşımlı hostingde APCu veya dosya tabanlı önbellekleme kullanılabilir.