Otomatik Yükleme Nedir; Spl_autoload, __autoload ve spl_autoload_register'ı nasıl kullanıyorsunuz?


204

Gelişmiş PHP standartlarını öğreniyorum ve yeni ve kullanışlı yöntemler uygulamaya çalışıyorum. Daha önce __autoloadher sayfada birden çok dosya içeren kaçmak için kullanıyordum , ama son zamanlarda bir ipucu gördüm__autoload manual

spl_autoload_register () , otomatik yükleme sınıfları için daha esnek bir alternatif sunar. Bu nedenle, __autoload () kullanılması önerilmez ve gelecekte kullanımdan kaldırılabilir veya kaldırılabilir.

ama nasıl uygulanacağını gerçekten anlayamıyorum spl_autoloadvespl_autoload_register

Yanıtlar:


337

spl_autoload_register() PHP'nin bir yığın / kuyruğa koyacağı ve "yeni Sınıf" bildirildiğinde sırayla çağıracağı birden çok işlevi (veya kendi Autoload sınıfınızdan statik yöntemleri) kaydetmenize olanak tanır.

Yani mesela:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

Yukarıdaki örnekte, "Sınıfım" örneklemeye çalıştığınız sınıfın adıdır, PHP bu adı bir dize olarak geçirir spl_autoload_register(), bu da değişkeni alıp uygun sınıfı / dosyayı "dahil etmek" için kullanmanızı sağlar . Sonuç olarak, bu sınıfı bir include / requir deyimi aracılığıyla eklemeniz gerekmez ...

Sadece yukarıdaki örnekte olduğu gibi somutlaştırmak istediğiniz sınıfı arayın ve spl_autoload_register()tüm sınıfınızın nerede olduğunu anlayacak olan kendi fonksiyonunuzu (üzerinden ) kaydettiğiniz için PHP bu fonksiyonu kullanacaktır.

Kullanmanın faydası spl_autoload_register()aksine olmasıdır __autoload()her dosyasında bir özdevinimli_yükle işlevi uygulamak gerekmez oluşturup buna. spl_autoload_register()ayrıca otomatik yüklemeyi hızlandırmak ve daha da kolaylaştırmak için birden fazla otomatik yükleme işlevini kaydetmenizi sağlar.

Misal:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

Spl_autoload ile ilgili olarak , el kitabı şunları belirtir:

Bu işlev, için varsayılan bir uygulama olarak kullanılmak üzere tasarlanmıştır __autoload(). Başka bir şey belirtilmezse ve spl_autoload_register()herhangi bir parametre olmadan çağrılırsa, bu işlev daha sonraki çağrılar için kullanılacaktır __autoload().

Daha pratik terimlerle, tüm dosyalarınız tek bir dizinde bulunuyorsa ve uygulamanızda yalnızca .php dosyaları değil, örneğin .inc uzantılı özel yapılandırma dosyaları kullanılıyorsa, kullanabileceğiniz bir strateji, dizininizi içeren PHP dosyalarına yol (yoluyla set_include_path()) içerir.
Ayrıca yapılandırma dosyalarınıza da ihtiyaç duyduğunuzdan spl_autoload_extensions()PHP'nin aramasını istediğiniz uzantıları listelemek için kullanabilirsiniz .

Misal:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

Spl_autoload, __autoload()sihirli yöntemin varsayılan uygulaması olduğundan, yeni bir sınıf oluşturmaya çalıştığınızda PHP spl_autoload'u çağırır.

Bu yardımcı olur umarım...


35
Bu, cevapların tarihindeki en iyi cevaplardan biri olabilir. Saygı. "OMG! Şimdi hepsi mantıklı!" senin yüzünden anlar, iyi adamım. Bence sadece bir fan kulübüne başlayabilirim.
Sadece Düz Yüksek

2
Bunu alternatif evrenlerde bile tüm cevapların en iyi cevabı yapmak için lütfen spl_autoload'u çok ekleyin, um, "yardımsever" (?) Tüm dosya adlarını küçük harfe dönüştürür (aşağıdaki yorumuma bakın @user). CapitalLettersAndStuff'ınızı beğendiyseniz spl_autoload_register () vanilyasını kullanamazsınız.
Sadece Düz Yüksek

6
@Just Plain High Bu sorunu yaşamıyorum ve tüm sınıf dosyalarım devrediliyor. BTW, bu harika bir cevap. Bu yazıyı okuyana kadar anlayamadığım basit bir kavramın etrafına geçmeme yardımcı oldu! Benim 85 (ve büyüyen) satır dahil tüm sınıf dosyalarımı içeren dosya şimdi 7 satır olduğunu!
kyle

2
Bu gerçekten iyi bir cevap ama bir şey eksik. Gerçek varsayılan işlev nedir? Bildiğim sınıflarla, ad alanını yol olarak ve sınıf adını dosya adı olarak kullanır. Rağmen fonksiyonları ile nasıl çalıştığını anlayamıyorum.
SiXoS

2
Tembel yüklerin dosyaları / sınıfları içermesinin (ve genel olarak) kullanılmasının büyük faydalarından biri değil mi? Bu, cevap tarafından ima edilir, ancak açıkça belirtilmez. Bana göre bu, cevabınıza dahil etmek için mükemmel olabilecek kritik bir bilgidir! :)spl_autoload_register()__autoload()
rinogo

13

PHP 5.3'ten beri, spl_autoload_register()ad alanlarıyla birlikte kullanabilirsiniz , bu da projenizi organize edebileceğiniz ve php sınıflarınızı herhangi bir gereksinim veya içermeden ve bir __autoload()işlevi yeniden tanımlamaksızın otomatik olarak yükleyebileceğiniz anlamına gelir .

Bu davranışı göstermek için index.php adlı bir dosya oluşturmanız yeterlidir:

<?php
spl_autoload_register();
var_dump(new Main\Application);

Ardından, index.php dosyasının hemen yanında bulunan Main adlı bir klasör oluşturun. Son olarak, Main içinde bulunan Application.php adlı bir dosya oluşturur ve içine aşağıdaki kodu yapıştırın:

<?php namespace Main;
class Application{}

9
Tüm bunlarla uğraştığım bir not: spl_autoload () - ve böylece spl_autoload_register () - dosya adlarını küçük harfe dönüştürür (hata raporlarına, hoş ve öfkeli oylamaya rağmen). Bu araçlar size "Ana \ Application" ama spl_autoload arıyor olabilir "ana \ uygulaması" aramaktadır. Eğer benim gibi develeri seviyorsanız, kendi fonksiyonunuzu yazmak zorunda kalacaksınız. Burada güzel bir başlangıç ​​örneği var: github.com/ircmaxell/PHP-CryptLib/blob/…
Just Plain High

1
Artıları: spl_autoload_register () otomatik yükleme Eksilerini en hızlı yöntemdir: sadece küçük harfli dosyalar / sınıflar ve ad alanları ile de çalışır, bu gün ve yaşta sadece büyük zaman sux (CamelCase vb kullanmak için söyleme seçeneği yok). Ancak namespace / classname.php yapısı ile yaşayabiliyorsanız, daha fazla bakmayın.
stamster

1
spl_autoload_register()varsayılan uygulama devralınan sınıfları bulamıyor. Bu yüzden, varsayılan olarak, küçük harfli dosyalar ve ad alanı yolunu yansıtan dizinler kullanarak, başka bir sınıfı (üst öğe) genişleten bir sınıfım olmadığı sürece her şey iyi çalışır. PHP daha sonra, aynı dizinde / ad alanında olsalar bile, bu ana sınıfı bulamadığı hatası verir! Şaşırtıcı olan şey, kelimenin tam anlamıyla sadece birinci seviye sınıfların bulunmasıdır, bu yüzden spl_autoload_register()manuel olarak eksik ebeveyn / miras alınan sınıfları dahil etmek için sadece birinciden sonra anonim işlev kuralı ile başka bir tane koymak zorunda kaldım .
stamster

1

İşte Autoload'u kullanmanın yolu. Verilen örnekte sınıfları 3 farklı dizinten yüklemek istiyorum.

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

Verilen örnekte PHP, bu üç farklı dosya adı biçimini kullanarak bu üç dizinde ad alanı \ sınıfını arayacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.