PHP'de Temiz, Modüler ve Yeniden Kullanılabilir Kod Yazma Rehberi

Sayfayı kopyala
Temiz, modüler ve yeniden kullanılabilir kod yazmak, profesyonel yazılım mühendisliğinin temel taşlarından biridir. Basit bir betik dilinden tip güvenli (type-safe) ve nesne yönelimli (OOP) güçlü bir dile dönüşen PHP ekosisteminde, temiz kod standartlarına uymak büyük ölçekli uygulamaların sürdürülebilirliği için kritik önem taşır.
💡 Özet (TL;DR):
- Temiz Kod: Okunması, yazılması ve bakımı kolay olan koddur. Tutarlı bir tarz (PSR-12) takip eder ve tekrarlardan kaçınır.
- SOLID Prensipleri: Kodun çürümesini engelleyen ve yazılımı esnek kılan beş tasarım ilkesidir (SRP, OCP, LSP, ISP, DIP).
- Modülerlik: Bağımlılık Enjeksiyonu (Dependency Injection - DI) kullanarak kodu küçük, bağımsız bileşenlere bölmektir.
- Otomasyon: Standartları uygulamak ve hataları erkenden yakalamak için PHP_CodeSniffer, PHPStan ve PHPUnit gibi araçlar kullanılır.
1. SOLID Prensipleri ve Pratik Uygulamaları
SOLID prensipleri teorik olarak çok konuşulsa da, bunları PHP üzerinde uygulamalı olarak görmek faydalarını daha net anlamamızı sağlar. En sık ihlal edilen iki ilkeye odaklanalım: SRP ve DIP.
Tek Sorumluluk İlkesi (Single Responsibility Principle - SRP)
Bir sınıfın değişmek için yalnızca tek bir nedeni olmalıdır.
❌ Kötü Pratik (SRP İhlali): Aşağıdaki sınıf kullanıcı kaydı, veritabanı işlemleri ve e-posta gönderimini tek bir yerde gerçekleştirmektedir.
class UserRegistration {
public function register(array $data) {
// Kullanıcı verilerini doğrula
// Veritabanına bağlan ve kaydet
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $db->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt->execute([$data['username'], $data['email']]);
// Hoş geldin e-postası gönder
mail($data['email'], "Welcome!", "Thanks for registering.");
}
}
✔️ İyi Pratik (SRP Uyumlu): Sorumlulukları veritabanı işlemleri için bir repository katmanına ve iletişim için bir e-posta servisine bölüyoruz.
class UserRepository {
private PDO $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function save(User $user): void {
$stmt = $this->db->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt->execute([$user->getUsername(), $user->getEmail()]);
}
}
class EmailService {
public function sendWelcomeEmail(string $email): void {
mail($email, "Welcome!", "Thanks for registering.");
}
}
class UserRegistration {
private UserRepository $repository;
private EmailService $emailService;
public function __construct(UserRepository $repository, EmailService $emailService) {
$this->repository = $repository;
$this->emailService = $emailService;
}
public function register(User $user): void {
$this->repository->save($user);
$this->emailService->sendWelcomeEmail($user->getEmail());
}
}
2. Bağımlılık Enjeksiyonu (Dependency Injection) ve Modülerlik
Modüler kod, gevşek bağlı (loosely coupled) küçük birimlerden oluşur. Sınıfların içinde sabit kodlu bağımlılıklar oluşturmak yerine, bu bağımlılıkları dışarıdan parametre olarak geçmek (Constructor Injection) en iyi yöntemdir (Yukarıdaki UserRepository örneğinde olduğu gibi).
Uygulamanız büyüdükçe bağımlılıkları yönetmek için bir DI Konteyneri (PHP-DI, Laravel Service Container veya Symfony DependencyInjection gibi) kullanmak, kod tabanını test edilebilir kılar ve birim testler sırasında sahte nesneler (mock) kullanmayı kolaylaştırır.
3. PSR Standartlarına Uyum
Yazdığınız kodun diğer geliştiriciler tarafından kolayca anlaşılabilmesi için PHP Framework Interop Group (PHP-FIG) tarafından belirlenen standartlara uymalısınız.
- PSR-1 (Temel Kodlama Standardı): Dosya yapısı, adlandırma kuralları (CamelCase sınıflar, büyük harf sabitler) ve ad alanları (namespaces) için temel kuralları belirler.
- PSR-12 (Genişletilmiş Kod Tarzı Kılavuzu): Kullanımdan kaldırılan PSR-2'nin yerini almıştır. Süslü parantezlerin konumlandırılması, girintileme (her zaman 4 boşluk, asla tab değil), satır uzunlukları ve tip tanımlamaları hakkında katı kurallar içerir.
Hızlı Bir PSR-12 Örneği:
namespace App\Services;
use App\Models\User;
class UserService
{
public function createUser(array $data): User
{
// 4 boşluk girinti, sınıf/metot süslü parantezleri alt satırda başlar
return new User($data);
}
}
Kod Kalitesi Karşılaştırma Tablosu
| Özellik | Eski / Spagetti Kod | Temiz ve Modüler Kod |
|---|---|---|
| Test Edilebilirlik | Zor, gerçek veritabanı ve SMTP sunucuları gerektirir | Kolay, bağımsız modüller mock nesnelerle kolayca test edilir |
| Bağımlılık (Coupling) | Yüksek (new anahtar kelimesi ile sıkı bağ) | Düşük (Arayüzler ve DI ile gevşek bağ) |
| Okunabilirlik | Karmaşık, uzun metotlar, iç içe geçmiş koşullar | Yüksek, tek bir işe odaklanmış kısa metotlar |
| Genişletilebilirlik | Mevcut özellikleri bozma riski yüksektir | Güvenli, Açık-Kapalı Prensibine (OCP) uygundur |
Sıkça Sorulan Sorular (FAQ)
Temiz kodda Arayüz (Interface) ve Soyut Sınıf (Abstract Class) farkı nedir?
Arayüzler (Interface), bir sınıfın ne yapabileceğini belirleyen davranış sözleşmeleridir, kod içermezler. Soyut Sınıflar (Abstract Class) ise ortak kod paylaşımını ve sınıfların bu davranışı nasıl gerçekleştireceğini tanımlamak için kullanılır.
PHP'de kod standartlarını nasıl otomatik hale getirebilirim?
Kod formatını manuel olarak kontrol etmeniz gerekmez. Aşağıdaki araçlarla bunu otomatikleştirebilirsiniz:
- PHP_CodeSniffer (PHPCS): Kodu inceler ve PSR-12 standartlarına göre otomatik olarak biçimlendirir.
- PHPStan / Psalm: Statik analiz araçlarıdır. Kodu çalıştırmadan tip hatalarını ve olası çalışma zamanı hatalarını yakalar.
- Laravel Pint / FriendsofPHP/PHP-CS-Fixer: Kod stilini otomatik düzelten araçlardır.
Singleton Tasarım Deseni kötü bir pratik midir?
Singleton klasik bir tasarım deseni olsa da, modern PHP dünyasında genellikle bir "anti-pattern" olarak kabul edilir. Küresel durumu (global state) yönettiği, birim testleri zorlaştırdığı ve bağımlılıkları gizlediği için Bağımlılık Enjeksiyonu (DI) neredeyse her zaman daha iyi bir seçenektir.
Resmi Kaynaklar
Bu Yazıda Yapılan Değişiklikler
- 20.06.2026: Yazı ilk kez yayınlandı (karşılaştırmalı kod örnekleri, SOLID uygulamaları, karşılaştırma tablosu ve İngilizce sürüm bağlantısı ile birlikte).
