PHP gerekli sınıfları dahil işlemek nasıl

8 Cevap php

Ben iyi uygulama ben kullanmak için gereken tüm sınıfları benim komut dosyası için erişilebilir olmasını sağlamak amacıyla benim PHP pek çok "include" zorunda ile sorunu ele için ne olduğunu merak ediyorum. Şu anda, ben sadece dahil kullanıyorum once to include the classes I access directly. Each of those would include eriştikleri sınıflar kez. Ben __ özdevinimli_yükle fonksiyonunu kullanarak içine baktım, ama şapka sizin sınıf dosyaları bir dizin ağacında organize olması planlıyorsanız iyi çalışmak için görünmüyor. Bunu yaptım eğer aradığınız sınıfı bulana kadar dizin ağacı yürüme bitirmek istiyorum gibi görünüyor. Ayrıca, bu farklı ad aynı adla sınıfları etkileri nasıl emin değilim.

Bu işlemek için kolay bir yolu var mı? Ya PHP sadece tüm pek çok farklı dizinlere olabilir ayrı dosyalarda bulunan farklı nesnelerin sürü için "enterprisey" türü uygulamalar uygun değildir.

8 Cevap

Benim uygulamalar Ben genellikle tüm çekirdek sınıfları (yani çerçeve ve beraberindeki kütüphaneler) içerir setup.php dosyası var. Benim özel sınıflar dizin düzeni harita ile destekli autoloader kullanılarak yüklenir.

Yeni bir sınıf eklenir her zaman ben o değerler olarak tuşları ve yolları gibi sınıf isimleri ile ilişkisel dizi oluşturur modeli sınıfları için arama bütün dizin ağacı tarar komut satırı oluşturucu komut dosyasını çalıştırın. Sonra, __ autoload işlevi o diziye sınıf adını arar ve yolunu içerir alır. İşte kod:

autobuild.php

define('MAP', 'var/cache/autoload.map');
error_reporting(E_ALL);
require 'setup.php';
print(buildAutoloaderMap() . " classes mapped\n");

function buildAutoloaderMap() {
    $dirs = array('lib', 'view', 'model');
    $cache = array();
    $n = 0;
    foreach ($dirs as $dir) {
        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $entry) {
            $fn = $entry->getFilename();
            if (!preg_match('/\.class\.php$/', $fn))
                continue;
            $c = str_replace('.class.php', '', $fn);
            if (!class_exists($c)) {
                $cache[$c] = ($pn = $entry->getPathname());
                ++$n;
            }
        }
    }
    ksort($cache);
    file_put_contents(MAP, serialize($cache));
    return $n;
}

autoload.php

define('MAP', 'var/cache/autoload.map');

function __autoload($className) {
    static $map;
    $map or ($map = unserialize(file_get_contents(MAP)));
    $fn = array_key_exists($className, $map) ? $map[$className] : null;
    if ($fn and file_exists($fn)) {
        include $fn;
        unset($map[$className]);
    }
}

Bu dosya adlandırma kuralı [class_name]. Class.php olması gerekir. Sınıfları autobuild.php baktım olacak dizinleri değiştirmek. Sınıf bulunamadı zaman da özdevinimli_yükle fonksiyonundan autobuilder çalıştırabilirsiniz, ama bu sonsuz döngü içine programı alabilirsiniz.

Tefrika diziler lanetlemek hızlı.

@ JasonMichael: PHP 4 ölü. Bunun üzerine alın.

Sen spl_autoload_register ile birden autoloading fonksiyonları tanımlayabilirsiniz:

spl_autoload_register('load_controllers');
spl_autoload_register('load_models');

function load_models($class){
    if( !file_exists("models/$class.php") )
    	return false;

    include "models/$class.php";
    return true;
}
function load_controllers($class){
    if( !file_exists("controllers/$class.php") )
    	return false;

    include "controllers/$class.php";
    return true;
}

Ayrıca program fiziksel dizinlere Haritayı yapılandırılmış adlandırma kuralları kullanarak sınıf dosyasının konumunu belirleyebilirsiniz. Bu Zend Zend Framework bunu nasıl. Yani Zend_Loader::loadClass("Zend_Db_Table"); bu çizgi üzerinde bölerek dizinleri bir diziye classname patlar ve ardından Zend_Loader sınıf gereken dosyayı yüklemek için gider çağırdığınızda.

Tüm Zend modülleri gibi, ben kendi sınıfları ile kendi üzerinde sadece yükleyici kullanabilirsiniz ama ben sadece zerdüştlerin MVC kullanarak bir sitenin parçası olarak kullanmıştır beklenebilir.

Eğer dinamik sınıf yüklemenin her türlü kullanabilirsiniz Ama örneğin this blog post sınıf dosyaları sabit yükleme ile Zend_Loader karşılaştırarak görmek, yük altında performans ile ilgili kaygılar olmuştur.

Yanı sıra PHP aramak zorunda performans ceza yolunu içerir, bu opcode önbelleğe alma yendi. Bu yazı üzerine bir yorum Gönderen:

HERHANGİ Dinamik sınıf yükleyicisi kullanırken APC dosyalar herhangi bir tek isteği üzerine yükler hangi onun emin değil tam olarak bu dosyaları önbelleğe olamaz. Sert yüklenerek dosyaları APC tam bunları önbelleğe alabilir.

Eğer onlar dizin ağacı içinde bulunan konum işlevini anlatmak sizin sınıflar için tutarlı bir adlandırma kuralı varsa __autoload iyi çalışır. Kolayca modelleri, görüş ve kontrolörler içine sınıfları ayırabilirsiniz, çünkü MVC bu tür bir şey için, özellikle de kendisi verir.

Alternatif olarak, sınıf yerleri dosya ve __autoload bu dizi sorgulamak izin isimlerden bir ilişkisel dizi tutun.

Şimdiye kadar önerilerin, ben Kevin kısmi değilim, ama mutlak olması gerekmez. Ben bir kaç farklı seçenek __ autoload ile kullanmak için bkz.

  1. Tek bir dizine tüm sınıf dosyaları koydum. Dosyayı adlandırın sınıftan sonra, yani classes/User.php veya classes/User.class.php.
  2. Kendi sınıflarının tüm MVC çerçevesi içine güzel uyum vs eğer, başka içine, bir dizine kontrolörleri modelini koyarak Kevin'in fikir iyi çalışır, ama bazen işler dağınık olsun.
  3. Classname dizini içerir. Örneğin, Model_User adında bir sınıf aslında classes/Model/User.php yer olurdu. Sizin __ özdevinimli_yükle işlevi dosyayı bulmak için bir dizin ayracı içine bir çizgi çevirmek bilemez.
  4. Sadece bir kere bütün dizin yapısını ayrıştırmak. __ Özdevinimli_yükle işlevi, hatta sadece onu tanımlanan aynı PHP dosyası ya, hangi dosyaları classes dizin ve önbellek içeriği üzerinde döngü nerede. Eğer User sınıf yüklemeye çalışın eğer classes/User.php öyle veya classes/Models/User.php veya classes/Utility/User.php Yani, bu önemli değil. O User.php yere classes dizininde bulduğunda, o User class özdevinimli gerektiğinde eklemek için dosya bilmek olacaktır.

Burada yayınlanan kod bir örnek oldu. Bu sadece php, include_path için modeller ve denetleyici klasörleri eklemek çok daha mantıklı olur.

Ben sadece spl_autoload_register birden fazla yükleyiciler tanımlayabilirsiniz beri autoload __ için daha iyi bir alternatif olduğuna işaret çalışıyordu, ve birbirleri ile çakışmaması olmaz. Handy siz de bir __ özdevinimli_yükle fonksiyon tanımlamak kütüphanelerini varsa.

@ Kevin:

Ben sadece spl autoload kayıt ve _autoload since you can define multiple loaders, and they won't conflict with each other. Handy if you have to include libraries that define an _ autoload işlevi için daha iyi bir alternatif olduğunu işaret çalışıyordu.

Emin misin? documentation farklı diyor ki:

Kodunuzu varolan _autoload function then this function must be explicitly registered on the _ özdevinimli_yükle yığını varsa. Spl autoload register () etkili _autoload function by either spl autoload () ya da SPL autoload () çağrısı için motor önbelleği yerini alacak olmasıdır.

=> Açıkça yanı sıra herhangi bir kütüphanenin __autoload kayıt var. Ama ayrı haklısın tabii olduğun dan, bu fonksiyon daha iyi bir alternatif olduğunu.

__autoload, ama iş sadece PHP 5 olacaktır.