2012-08-22 24 views

回答

28

你問極其輕便易於安裝,讓我們這樣做;)

蒂莫西Boronczyk寫了一個很好的最小SPL自動加載磁帶機:http://zaemis.blogspot.fr/2012/05/writing-minimal-psr-0-autoloader.html

我凝結像這樣的代碼:

function autoload1($class) { 
    preg_match('/^(.+)?([^\\\\]+)$/U', ltrim($class, '\\'), $match)); 
    require str_replace('\\', '/', $match[ 1 ]) 
     . str_replace([ '\\', '_' ], '/', $match[ 2 ]) 
     . '.php'; 
} 

然後將此[autoload3]與short @Alix Axel code [autoload4]進行比較(縮小版本):

function autoload3($c){preg_match('/^(.+)?([^\\\\]+)$/U',ltrim($c,'\\'),$m);require str_replace('\\','/',$m[1]).str_replace(['\\','_'],'/',$m[2]).'.php';} 
function autoload4($c){require (($n=strrpos($c=ltrim($c,'\\'),'\\'))!==false?str_replace('\\','/',substr($c,0,++$n)):null).str_replace('_','/',substr($c,$n)).'.php';} 

autoload3是最短的!

讓我們用穩定&非常輕量級(175B!)自動加載文件:

<?php spl_autoload_register(function ($c){preg_match('/^(.+)?([^\\\\]+)$/U',ltrim($c,'\\'),$m);require str_replace('\\','/',$m[1]).str_replace(['\\','_'],'/',$m[2]).'.php';}); 

也許我瘋了,但你問的極端,不是嗎?

編輯:感謝阿利克斯阿克塞爾,我已經縮短了代碼(!只有100B),並使用包括替代的情況下,需要你有一箇舊的庫(和SPL autoload棧裏,然後各種自動加載各種自動加載策略。 ..)。

<?php spl_autoload_register(function($c){@include preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';}); 

如果您想使其更短/更好,請使用此gist

+4

+1,我還沒有試過,但我認爲,如果你使用'的preg_replace()',而不是'的preg_match()'+'str_replace()函數'你的版本可能會更短。 –

+1

我不能完全肯定'的preg_match ()'比其他等價的PHP選項更快。 – TCB13

15

PSR-0 specification document具有發明實施例一兼容的自動加載功能已經很短:

function autoload($className) 
{ 
    $className = ltrim($className, '\\'); 
    $fileName = ''; 
    $namespace = ''; 
    if ($lastNsPos = strripos($className, '\\')) { 
     $namespace = substr($className, 0, $lastNsPos); 
     $className = substr($className, $lastNsPos + 1); 
     $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; 
    } 
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; 

    require $fileName; 
} 

它的使用是非常簡單的:

spl_autoload_register('autoload'); 

與它的缺點是,你需要配置它的基本目錄與include_path指令一起工作。爲了支持混合PSR-0自動加載機上靠在SPL語義,以下一個supportss包括路徑和SPL自動加載擴展:

$spl_autoload_register_psr0 = function ($extensions = null) 
{ 
    $callback = function ($className, $extensions = null) 
    { 
     if (!preg_match('~^[a-z0-9\\_]{2,}$~i', $className)) { 
      return; 
     } 
     null !== $extensions || $extensions = spl_autoload_extensions(); 
     $extensions = array_map('trim', explode(',', $extensions)); 
     $dirs = array_map('realpath', explode(PATH_SEPARATOR, get_include_path())); 

     $classStub = strtr($className, array('_' => '/', '\\' => '/')); 

     foreach ($dirs as $dir) { 
      foreach ($extensions as $extension) { 
       $file = sprintf('%s/%s%s', $dir, $classStub, $extension); 
       if (!is_readable($file)) { 
        continue; 
       } 
       include $file; 
       return; 
      } 
     } 
    }; 

    return spl_autoload_register($callback); 
}; 

The Symfony2 ClassLoader Component具有允許這裏多個配置的益處。您可以通過Pear或Composer輕鬆安裝(symfony/class-loader on Packagist)。它本身就是一個組件,被許多人使用,並且經過了相當充分的測試和支持。

+0

舉例PSR-0自動加載接受的擴展和對標準的PHP工作包括路徑:http://chat.stackoverflow.com/transcript/message/9066049#9066049 – hakre

+0

刪除str_replace函數(「_」,......爲我工作。 – itsoft3g

4

the answer @hakre provided完全等效,只是短:

function autoload($class) { 
    $path = null; 

    if (($namespace = strrpos($class = ltrim($class, '\\'), '\\')) !== false) { 
    $path .= strtr(substr($class, 0, ++$namespace), '\\', '/'); 
    } 

    require($path . strtr(substr($class, $namespace), '_', '/') . '.php'); 
} 

您還可以通過更改$path = null;到另一個值設置的基本目錄,或者只是這樣做:

$paths = array 
(
    __DIR__ . '/vendor/', 
    __DIR__ . '/vendor/phunction/phunction.php', 
); 

foreach ($paths as $path) 
{ 
    if (is_dir($path) === true) 
    { 
     spl_autoload_register(function ($class) use ($path) 
     { 
      if (($namespace = strrpos($class = ltrim($class, '\\'), '\\')) !== false) 
      { 
       $path .= strtr(substr($class, 0, ++$namespace), '\\', '/'); 
      } 

      require($path . strtr(substr($class, $namespace), '_', '/') . '.php'); 
     }); 
    } 

    else if (is_file($path) === true) 
    { 
     require($path); 
    } 
} 
0

這不是直接回答這個問題,但我發現,上述答案的工作在獨立的PHP腳本很大,但在一定的框架,如Joomla等使用時造成了問題。

對於使用Joomla的人,事實證明,已經有內置的框架兼容的自動加載,所以你不會需要使用上述功能。在這種情況下,只需撥打JLoader :: registerNamespace()......例如:

JLoader::registerNamespace('Solarium', JPATH_LIBRARIES . DS . 'solarium-3.2.0' . DS . 'library'); 
0
function autoload($fullClassName) { 
    $name_elems = explode('\\', $fullClassName); 
    require __DIR__.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $name_elems).'.php'; 
} 

這甚至支持喜歡的東西: $ transformerContstraint =新\ Recurr \變壓器\約束\ AfterConstraint(新約會時間());

只是把它放在/vendor/Recurr/Transformer/Constraint/AfterConstraint.php