2012-08-22 12 views

Odpowiedz

28

Pytasz niezwykle lekki, zróbmy tak;)

Timothy Boronczyk napisał piękny minimalny SPL autoloadery: http://zaemis.blogspot.fr/2012/05/writing-minimal-psr-0-autoloader.html

I skondensowany kod tak:

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

Następnie porównaj (zmodernizowane wersje) tego [autoload3] z 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 jest najkrótszy!

Użyjmy stabilną & niezwykle lekkie (175b!) Plik autoloadera:

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

Może jestem szalony, ale poprosiłeś dla ekstremalnych, nie?

EDIT: Dzięki Alix Axel, mam skrócić kod (!) I tylko 100b stosowane obejmują zamiast wymagać w przypadku gdy masz różne strategię autoloading dla starych bibliotekami (i wtedy różnym autoloaderze w spl autoload stosie. ..).

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

Jeśli chcemy, aby było krótsze/lepiej, skorzystaj z tego gist.

+4

+1, nie próbowałem, ale myślę, że twoja wersja może być jeszcze krótsza, jeśli użyjesz 'preg_replace()' zamiast 'preg_match()' + 'str_replace()'. –

+1

Nie jestem całkowicie pewien, że 'preg_match() 'jest szybszy niż inne równoważne opcje PHP. – TCB13

15

PSR-0 specification document ma przykładowy zgodną funkcję autoloader, który jest już bardzo krótki:

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; 
} 

To jest użycie jest bardzo proste:

spl_autoload_register('autoload'); 

Wadą z nim jest to, że trzeba skonfigurować katalogi podstawowe działa z dyrektywą include_path. Aby wesprzeć hybrydę PSR-0 Autoloadery oparł się na SPL semantyki, następujące jeden supportss zawierać ścieżkę i SPL autoload rozszerzeń:

$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 ma tę zaletę, aby umożliwić bardziej konfigurację tutaj. Możesz go łatwo zainstalować za pomocą Pear lub Composer (symfony/class-loader on Packagist). Jest to komponent sam w sobie, który jest używany przez wielu i dość dobrze przetestowany i obsługiwany.

+0

Przykład autoloadera PSR-0 akceptujący rozszerzenia i działający na standardowej ścieżce PHP include: http://chat.stackoverflow.com/transcript/message/9066049#9066049 – hakre

+0

Usunięcie str_replace ('_', ... dla mnie działało. – itsoft3g

4

Dokładny odpowiednik the answer @hakre provided, tylko krótsze:

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'); 
} 

Można również ustawić katalog bazowy zmieniając $path = null; na inną wartość, lub po prostu zrobić tak:

$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

To nie jest bezpośrednia odpowiedź na to pytanie, ale stwierdziłem, że powyższe odpowiedzi działały świetnie na samodzielnych skryptach PHP, ale powodowały problemy, gdy były używane w pewnych frameworkach, takich jak Joomla.

Dla każdego, kto używa Joomla, okazuje się, że istnieje kompatybilny autoloader już wbudowany w framework, dlatego nie będziesz musiał używać powyższych funkcji. W tym przypadku, po prostu zadzwoń JLoader :: registerNamespace() .... na przykład:

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'; 
} 

ten obsługuje nawet takie rzeczy jak: $ transformerContstraint = new \ Recurr Transformer \ \ \ ograniczeniami AfterConstraint (nowa DateTime());

Wystarczy umieścić go w /vendor/Recurr/Transformer/Constraint/AfterConstraint.php

Powiązane problemy