PSR-4 ve otomatik yükleme: include zincirinden kurtulmak
Sınıfları elle dahil etmeyi bırakıp standart otomatik yüklemeye geçmek: PSR-0 ve PSR-4 farkı, Composer entegrasyonu.
Geçen ay Composer’a geçişi anlattım. O yazıda autoload bölümünden kısaca söz etmiştim. Bu sefer daha ayrıntılı ele almak istiyorum çünkü PSR-4 ve autoloading konusu başlı başına bir alışkanlık değişikliği istiyor.
Eski alışkanlığım şuydu: her dosyanın başına hangi sınıflara ihtiyaç duyuyorsam onları require_once ile dahil etmek. Proje büyüdükçe bu liste de büyüyordu. Bazı dosyalarda on satırı aşan require_once zinciri görüyordum.
<?php
require_once 'lib/Database.php';
require_once 'lib/User.php';
require_once 'lib/Auth.php';
require_once 'helpers/Validator.php';
// ... devam ediyor
Bu yaklaşımın birkaç sorunu var: hangi dosyanın nerede olduğunu takip etmek zorunda kalıyorsunuz, yolu yanlış yazınca hata alıyorsunuz, klasör taşırsanız her require’ı güncellemeniz gerekiyor. Üstelik bir sınıf birden fazla yerde include edilirse PHP uyarı veriyor; require_once bunu önler ama şişirir.
Bir keresinde bir sınıfı yeniden adlandırdım ve o sınıfı kullanan yedi farklı dosyada require_once yolunu elle güncellemem gerekti. O gün bu düzenin sürdürülebilir olmadığını anladım.
PSR nedir?
PSR (PHP Standards Recommendation), PHP-FIG (PHP Framework Interop Group) tarafından yayımlanan uygulama standartlarıdır. PHP kütüphanelerinin ve framework’lerinin birbirleriyle uyumlu çalışabilmesi için ortak kurallar belirler.
Otomatik yüklemeyle ilgili iki standart var: PSR-0 ve PSR-4. İkisi de sınıf ismiyle dosya yolu arasında bir eşleme tanımlar.
PSR-0 ve PSR-4 farkı
PSR-0, 2009’da ortaya çıktı ve namespace ayracı \ ile alt çizgiyi _ her ikisini de dizin ayracı olarak kabul ediyordu. Bu yüzden Vendor_Package_ClassName gibi eski isimlendirme sistemleriyle uyumluydu.
Vendor\Package\ClassName → vendor/Package/ClassName.php
Vendor_Package_ClassName → vendor/Package/ClassName.php
PSR-4, PSR-0’ın getirdiği karmaşıklığı azaltmak için geldi. Yalnızca namespace ayracı \ kullanıyor, alt çizgi çevirisini kaldırdı. Daha temiz ve öngörülü:
App\Http\Controller → src/Http/Controller.php
PSR-4 şu an aktif standart; PSR-0 kullanımdan kalkıyor. Yeni projelerde PSR-4 kullanın.
Composer ile PSR-4 kurulumu
composer.json’a autoload bölümü ekliyorsunuz:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Bu şu anlama geliyor: App\ ile başlayan her sınıfı src/ klasöründe ara. Örneğin App\Http\UserController sınıfını src/Http/UserController.php dosyasında bul.
Sonra autoload haritasını oluşturuyorsunuz:
composer dump-autoload
Ve projenizin giriş noktasına tek satır:
<?php
require 'vendor/autoload.php';
$controller = new App\Http\UserController();
require_once zinciri bitti. Artık sınıfı kullandığınızda PHP otomatik olarak dosyayı buluyor.
Dizin yapısı
PSR-4 ile dizin yapısı namespace yapısını yansıtır:
src/
├── Http/
│ ├── UserController.php → App\Http\UserController
│ └── PostController.php → App\Http\PostController
├── Models/
│ └── User.php → App\Models\User
└── Services/
└── Mailer.php → App\Services\Mailer
Bu düzen projenin büyümesiyle birlikte çok daha kolay yönetilebiliyor. Yeni bir sınıf eklemek için sadece doğru klasöre dosyayı koyuyorsunuz; başka hiçbir yeri güncellemenize gerek yok.
Namespace yapısı ile dizin yapısının birbirini yansıtması, projenin nerede ne olduğunu kolayca tahmin etmenizi sağlıyor. App\Services\Mailer sınıfını aramak istediğinizde doğrudan src/Services/Mailer.php dosyasına gidiyorsunuz. Bu, projeye yeni katılan birisinin de hızla oryantasyon kurmasını kolaylaştırıyor.
Birden fazla namespace
Projenizin birden fazla ad alanı varsa hepsini tanımlayabilirsiniz:
{
"autoload": {
"psr-4": {
"App\\": "src/",
"Tests\\": "tests/"
}
}
}
Klasmap (classmap) seçeneği
PSR-0/PSR-4 dışında kalan eski kodlar için classmap var. Composer belirttiğiniz klasörü tarar ve her sınıfı dosyayla eşler:
{
"autoload": {
"classmap": ["lib/"]
}
}
Bu seçenek adlandırma kuralı olmayan eski kodları sisteme dahil etmek için kullanışlı. Ama yeni yazdığınız kod için PSR-4’ü tercih edin.
classmap ile PSR-4 arasındaki pratik fark şu: classmap her composer dump-autoload çalıştırdığınızda klasörü yeniden tarar ve statik bir eşleme üretir. PSR-4 ise kuralı çalışma zamanında uyguladığından dosyayı doğru konuma koymanız yeterli; dump-autoload çalıştırmanıza gerek yok. Bu gelişme sürecinde küçük bir konfora dönüşüyor.
Sonuç
PSR-4 ve Composer autoload’u benimsemek küçük bir değişiklik gibi görünse de günlük çalışmada ciddi fark yaratıyor. Elle require yazmak zorunda kalmıyorsunuz, dizin taşımaları daha az acı veriyor ve projeniz diğer PSR uyumlu kütüphanelerle sorunsuz çalışıyor. Framework kullanmasanız bile bu standartı benimsemek kod tabanınızı düzenli tutuyor.