Verimli PHP otomatik yükleme ve adlandırma stratejileri

4 Cevap php

Çoğu web geliştiricileri gibi bu gün, ben iyice web uygulamaları ve siteleri için katı MVC mimarisinin avantajlarını yaşıyorum. PHP ile MVC yaparken, autoloading tabii ki son derece kullanışlı oluyor.

Eğer her biri kendi autoloading kullanan farklı taban modülleri birleştiren bu besbelli daha esnek olduğu gibi ben, spl_autoload_register over simply defining a single __autoload() fonksiyonunun bir hayranı oldum. Ancak, ben yazmak yükleme işlevleri hakkında büyük hissetmemiştim. Onlar yüklemek mümkün sınıflar için bakmak için dize denetimi ve dizin tarama bir sürü içerir.

Örneğin, ben PATH_APP olarak tanımlanan bir temel yolu olan bir uygulamayı, ve adında dizinleri ile basit bir yapıya sahip diyelim models, views ve {[( 3)]}. Ben sık sık dosya IndexView.php adında sayede bir adlandırma yapısını istihdam ve IndexController.php uygun dizine iç ve modelleri genellikle varsayılan olarak belirli bir düzeni var. I-spl_autoload_register kayıtlı olur bu gibi, bu yapı için bir yükleyici fonksiyonu olabilir:

public function MVCLoader($class)
{
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) {
        require_once(PATH_APP.'/models/'.$class.'.php');
        return true;
    }
    else if (strpos($class,'View') !== false) {
        if (file_exists(PATH_APP.'/views/'.$class.'.php')) {
            require_once(PATH_APP.'/views/'.$class.'.php');
            return true;
        }
    }
    else if (strpos($class,'Controller') !== false) {
        if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) {
            require_once(PATH_APP.'/controllers/'.$class.'.php');
            return true;
        }
    }
    return false;
}

Bundan sonra bulunamadı değilse, ben modelleri dizinde alt dizinleri taramak için başka bir işlevi olabilir. Ancak, tüm / else-ing, dize kontrol ve dizin tarama bana verimsiz görünüyor ve bunu geliştirmek istiyorsanız.

Ben diğer geliştiriciler istihdam olabilir hangi dosya adlandırma ve autoloading stratejileri çok merak ediyorum. Ben autoloading alternatifi değil iyi teknikleri verimli autoloading için istihdam için özellikle arıyorum, ve ben.

4 Cevap

Bu benim (düz sonuncusunun kaynağından kaldırdı) benim tüm projelerinde kullanıyor ne olduğunu:

public static function loadClass($class)
{
    $files = array(
        $class . '.php',
        str_replace('_', '/', $class) . '.php',
    );
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path)
    {
        foreach ($files as $file)
        {
            $path = "$base_path/$file";
            if (file_exists($path) && is_readable($path))
            {
                include_once $path;
                return;
            }
        }
    }
}

Ben akımının her dizinde köklü SomeClass / SeperatedWith / Underscores.php ardından bu SomeClass_SeperatedWith_Underscores.php arayacaktır SomeClass_SeperatedWith_Underscores bakarsanız yolunu içerir.

EDIT: Ben sadece geliştirmede verimlilik için kullanmak, ve mutlaka vakit işlemiyor ki orada koymak istedim. Eğer yolda PEAR varsa, o zaman bu size sadece sınıfları kullanabilir ve bunları gerektiğinde onları dahil etmek zorunda değilsiniz.

Ben alt çizgi ad kesiliyor, dizinleri bir hiyerarşi içinde benim sınıfları tutmak eğilimindedir ... Bu kod I (için isterseniz bana istiyorsanız güzel ve derli toplu dosya yapısını korumak veya iç içe dizin olmadan hızlı bir sınıf dosyası enjekte sağlar ben şu anda üzerinde çalışıyorum projenin parçası değil Sanık, ama bir kütüphane, tek bir sınıf ya da iki ekleyerek.)

Ben bu çözüm indi:

Ben (ayrı modüller / sistemleri için alt klasörler içerir) benim sınıf kütüphanesi klasörünü erişir ve sınıf tanımları arıyor dosya içeriğini ayrıştırmak tek bir komut dosyası oluşturulur. Bir php dosyasında bir sınıf tanımı (oldukça basit regex desen) bulursa, bir sembolik bağ oluşturur:

class_name.php -> actual/source/file.php

Bu bana ana sembolik bağ klasöre yalnızca sınıf adını ve yolunu gereken bir tek, basit autoload fonksiyonunu kullanmanızı sağlar ve herhangi bir yol / string manipülasyon yapmak zorunda değildir.

Iyi bölüm tamamen benim kaynak kodu yeniden düzenlemek veya yeni bir alt sistemi eklemek ve sadece her şeyi özdevinimli sahip bağlantı üreten komut dosyası çalıştırabilirsiniz olmasıdır.

Eğer verim istiyorsanız o zaman hiç özdevinimli_yükle özelliğini kullanarak olmamalıdır. Özdevinimli_yükle özelliği tembel olmak için değildir. Eğer onları eklediğinizde sizin dosyaları dahil etmek için açık bir yol sağlamak olmalıdır. Lütfen özdevinimli_yükle fonksiyonu bu dosyaları bulabilirsiniz Eğer açıkça onları bulmak için kod olabilir. Eğer kod görünümü parçası üzerinde çalıştıklarını ve yaklaşık özdevinimli_yükle işlevi ele vererek, yeni bir görünüm sınıfı yüklemek için, bu birinci sınıf bir model sınıf olduğunu varsayar? Bu verimsiz. Bunun yerine, kodun olmalıdır:

include_once $this->views_path . $class . '.php';

Birden "view" yolları gerekiyorsa, görüşlerini yükleyen bir işlev yapmak:

public function load_view($class) {
    // perhaps there's a mapping here instead....
    foreach ($this->views_paths as $path) {
        $filename = $path . $class . '.php';
        if (file_exists($filename)) {
            include_once $filename;
        }
    }
    throw ....
}

Her durumda, meydana dahil noktada, size yüklemek istediğiniz sınıfı hakkında büyük / en doğru bilgiye sahip. Tam sınıfı yüklemek için bu bilgileri kullanarak verimli tek sınıf yükleme stratejisidir. Evet, daha fazla sınıf değişkenleri ya da (Allah korusun) bazı evrensel değişkenler ile sona erebilir. Ama bu sadece tembel olmak ve sınıf için dosya sisteminin parçalarını tararken daha iyi bir takas olduğunu.

Ben dahil başlatmasını ve yüklenebilir modülleri başlatılıyor önemser bir sınıf var. Tüm yüklenebilen modüller ortak bir taban sınıfından. Benim Örnekleyicide sınıfının bir yöntem argümanı gibi bir modül adını alır ve dinamik include bu modülün kaynak dosyası, bunun bir nesne örneğini ve başlatabilirsiniz. Modül 'model' bir parçası ise, örneğin, bu DB nesne geçirilir. Daha sonra yeni bir nesne döndürülür.

Controls.inc.php itibaren (evet, biraz PHP4-y var).

class controls
{
    function &getcontrol($objecttype)
    {		
    	require_once(RESOURCE_DIR . "nodecontrols/$objecttype.inc.php");
    	$control = &new $objecttype($this->db);
    	return $control;
    }

    ...
}

Ben bu nesneyi örneğini gerektiğinde, yapmam

$nodefetcher = $this->controls->getcontrol('nodefetcher');

$ Kontrolleri-> GetControl zaten (Require_once) olmamıştır eğer, doğru dosyayı dahil onu başlatmasını ve bu DB nesneyi geçen iş yapar.

Dikkat etmeniz gereken şeyler:

  • Kullanıcı girişi bölü ve dosya yükleme gelmemeli dahil edilerek örneğin, dahil yolunu zehir değil emin olun. Gerekli filtre $ objekttyp Eğer öyleyse sadece harfler ve rakamlar içerebilir, ve eğer bu olmuyorsa bir istisna atar.