- Konu sahibi
- #1
PHP autoload nasıl çalışır?
PHP autoload, ihtiyaç duyulan sınıf, arayüz, trait veya enum henüz yüklenmemişken ilgili PHP dosyasını otomatik olarak bulup çalıştırma mekanizmasıdır. Böylece her sınıf için baştan
require veya include yazmak yerine, sınıf adından dosya yolu üretilir ve dosya gerektiği anda yüklenir. En yaygın temel araç spl_autoload_register() fonksiyonudur.Çalışma mantığı
Kodda henüz tanımlanmamış bir sınıf kullanıldığında PHP, kayıtlı autoloader işlevlerini sırayla çağırır. Autoloader sınıf adını alır, bu ada karşılık gelen dosya yolunu hesaplar ve dosyayı
require ile yükler. Dosya doğru sınıfı tanımlıyorsa kod çalışmaya devam eder; dosya bulunamazsa veya sınıf adı ile dosyadaki tanım uyuşmazsa genellikle Class not found hatası alınır.Bir autoloader dosyayı bulamazsa çoğunlukla sessizce
return eder. Böylece başka bir kayıtlı autoloader sınıfı denemeye devam edebilir. Autoloader dosyayı yükler; sınıf bildirimi dosyanın içindedir. Bu dar örneğe istemcinin seçtiği keyfî sınıf adını geçirmeyin; üretimde Composer gibi sınanmış eşleyici tercih edin.Çalışan en küçük namespace örneği
Aşağıdaki örnekte
App\ namespace'i src/ klasörüne eşlenir. Her namespace parçası klasör, sınıf adı ise .php uzantılı dosya olarak kabul edilir.Dosya yapısı:
Kod:
project/
├── bootstrap.php
├── src/
│ └── Hello.php
└── public/
└── index.php
src/Hello.php içeriği:
Kod:
<?php
declare(strict_types=1);
namespace App;
final class Hello
{
public function message(): string
{
return 'Merhaba, autoload çalıştı.';
}
}
bootstrap.php içeriği:
Kod:
<?php
declare(strict_types=1);
spl_autoload_register(function (string $class): void {
$prefix = 'App\\';
$baseDirectory = __DIR__ . '/src/';
if (strncmp($class, $prefix, strlen($prefix)) !== 0) {
return;
}
$relativeClass = substr($class, strlen($prefix));
$file = $baseDirectory
. str_replace('\\', '/', $relativeClass)
. '.php';
if (is_file($file)) {
require $file;
}
});
public/index.php içeriği:
Kod:
<?php
require dirname(__DIR__) . '/bootstrap.php';
echo (new App\\Hello())->message();
Uygulamak için şu adımları izleyin:
- Örneği mevcut dosyalar üzerine yazmadan yeni boş bir klasörde, güncel PHP CLI ile değerlendirin. Dosyaları gösterilen klasör ve adlarla oluşturun. Linux gibi büyük-küçük harfe duyarlı sistemlerde
Hello.phpilehello.phpaynı kabul edilmez. - Proje kök dizininde
php public/index.phpkomutunu çalıştırın. - Beklenen çıktı
Merhaba, autoload çalıştı.metnidir. Bu çıktı,App\Hellosınıfı kullanılınca autoloader'ınsrc/Hello.phpdosyasını bulup yüklediğini gösterir. - Çıktı yerine
Class "App\Hello" not foundbenzeri hata alırsanız önce namespace, sınıf adı, dosya adı, büyük-küçük harf vebootstrap.phpyolunu karşılaştırın. Dosya yolu doğru olmasına rağmen hata sürüyorsa dosyanın gerçektenApp\Hellosınıfını tanımladığını kontrol edin.
Bu örneğin sınırlaması, yalnızca
App\ namespace'i için yazılmış olmasıdır. Başka namespace'ler, farklı kök klasörler veya daha karmaşık bağımlılıklar için eşleme kurallarını genişletmek gerekir.Autoload yöntemleri arasındaki karar
Küçük bir projede elle yazılmış bir callback yeterli olabilir. Birden fazla namespace ve üçüncü taraf paket kullanan projelerde ise autoload dosyasını elle sürdürmek yerine Composer'ın oluşturduğu autoloader tercih edilir. Temel fikir değişmez: namespace sınıf dosyasının yoluna çevrilir ve dosya sınıf ilk kullanıldığında yüklenir.
| Yöntem | Ne zaman uygun? | Dikkat edilmesi gereken |
|---|---|---|
Elle require | Çok az sayıda sabit dosya | Dosya listesi büyüdükçe bakım zorlaşır |
spl_autoload_register() | Küçük veya özel kurallı uygulamalar | Namespace ve dosya yolu eşlemesi size aittir |
| Composer autoloader | Namespace ve paket kullanan projeler | Üretilen autoload dosyasını uygulamaya dahil etmek gerekir |
Sık yapılan hatalar
- Autoloader'ı sınıf kullanılmadan önce kaydetmemek.
spl_autoload_register()çağrısı, sınıf örneği oluşturulmadan veya statik üyeye erişilmeden önce çalışmış olmalıdır. - Namespace ile klasör yapısını karıştırmak.
App\Service\Mailiçin bu örnekte beklenen dosya yolusrc/Service/Mail.phpolur. - Sınıf dosyasının sonunda farklı bir sınıf tanımlamak. Autoloader dosyayı bulsa bile beklenen tam sınıf adı oluşmamışsa hata devam eder.
- Gereksiz yere her dosyada aynı autoloader'ı kaydetmek. Autoloader kaydı genellikle uygulamanın giriş noktasında veya tek bir bootstrap dosyasında yapılmalıdır.
- Dosya yolunu işletim sistemine göre sabit ayırıcıyla üretmek. Namespace ayırıcılarını
/yol ayırıcısına dönüştürmek taşınabilirliği artırır.
Sık sorulan sorular
Autoload sınıfı bellekte sürekli tutar mı?
Autoload öncelikle sınıf tanımının bulunduğu dosyayı yükler. Sınıfın kullanım ömrü ve bellekteki davranışı ayrıca PHP çalışma modeli ile ilgilidir; autoload bir önbellekleme sistemi değildir.
Birden fazla autoloader kullanılabilir mi?
Evet.
spl_autoload_register() birden fazla callback kaydetmeye izin verir. Her callback kendi namespace veya dosya eşleme kuralını deneyebilir; bu nedenle kuralların birbiriyle çakışmaması gerekir.Autoload ile sınıf dosyası otomatik olarak doğru adlandırılır mı?
Hayır. Dosya adı, klasör yapısı, namespace ve sınıf bildirimi arasındaki kuralı autoloader belirler. PHP, keyfi dosya adlarını sınıf adına kendiliğinden eşleştirmez.