2012-08-22 16 views

risposta

28

Voi chiedete estremamente leggero, cerchiamo di fare in modo;)

Timothy Boronczyk ha scritto un bel autoloader SPL minima: http://zaemis.blogspot.fr/2012/05/writing-minimal-psr-0-autoloader.html

ho condensato il codice come questo:

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

confrontare Poi (versioni minified di questo) [autoload3] con 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 è il più breve!

Usiamo stabile & estremamente leggero (175b!) File autoloader:

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

Forse sono pazzo, ma hai chiesto estremo, no?

EDIT: Grazie a Alix Axel, ho abbreviare il codice (! Solo 100b) e utilizzati comprendono, invece di richiedere nel caso in cui si dispone di diverse strategie caricamento automatico per le vecchie librerie (e poi vari caricatore automatico a caricamento automatico pila spl. ..).

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

Se vuoi per renderlo più breve/meglio, si prega di utilizzare questo gist.

+4

+1, non l'ho provato ma penso che la tua versione potrebbe essere ancora più breve se usi 'preg_replace()' invece di 'preg_match()' + 'str_replace()'. –

+1

Non sono del tutto sicuro che 'preg_match() 'è più veloce di altre opzioni PHP equivalenti. – TCB13

15

Il PSR-0 specification document ha un esemplare funzione di caricatore automatico compatibile che è già piuttosto breve:

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

E 'utilizzo è piuttosto semplice:

spl_autoload_register('autoload'); 

Il difetto con esso è, che è necessario configurare directory di base funziona con la direttiva include_path. Per supportare un ibrido PSR-0 caricatori automatici appoggiati sulla semantica SPL, la seguente supportss includono percorso e autoload spl estensioni:

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

Il The Symfony2 ClassLoader Component ha il vantaggio di consentire una maggiore configurazione qui. Puoi installarlo facilmente tramite Pear o Composer (symfony/class-loader on Packagist). È un componente a sé stante che viene utilizzato da molti e abbastanza ben testato e supportato.

+0

Esempio per il caricatore automatico PSR-0 che accetta le estensioni e che lavora sul percorso standard di PHP include: http://chat.stackoverflow.com/transcript/message/9066049#9066049 – hakre

+0

Rimozione di str_replace ('_', ... ha funzionato per me. – itsoft3g

4

un esatto equivalente di the answer @hakre provided, appena più corta:

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

È anche possibile impostare la directory di base modificando $path = null; ad un altro valore, o semplicemente fare come questo:

$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

Questa non è una risposta diretta alla domanda, ma ho trovato che le risposte di cui sopra funzionavano alla grande sugli script PHP autonomi, ma che causavano problemi quando venivano utilizzati in alcuni framework, come Joomla.

Per chiunque utilizzi Joomla, risulta che esiste già un autoloader compatibile integrato nel framework, pertanto non sarà necessario utilizzare le funzioni sopra. In quel caso, basta chiamare JLoader :: registerNamespace() .... per esempio:

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

Questo supporta anche cose come: $ transformerContstraint = new \ Recurr \ Transformer \ Constraint \ AfterConstraint (nuova Appuntamento());

Basta mettere in /vendor/Recurr/Transformer/Constraint/AfterConstraint.php