PHP-najlżejszy Autoloader zgodny z psr-0

Mam małą aplikację, do której potrzebuję autoloadera. Z łatwością mógłbym użyć loadera klasy symfony2, ale wygląda to na przesadę.

Czy istnieje stabilny, niezwykle lekki autloader psr-0?

Author: hakre, 2012-08-23

7 answers

Prosisz bardzo lekko, zróbmy to;)

Tymoteusz Borończyk napisał fajny Autoloader minimal SPL: http://zaemis.blogspot.fr/2012/05/writing-minimal-psr-0-autoloader.html

Skondensowałem 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 (minifikowane wersje) tego [autoload3] z krótkim kodem @ Alix Axel [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 !

Zastosujmy stabilny i niezwykle lekki (175b !) plik autoloader :

<?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 prosiłeś o ekstremalne, nie?

EDIT: Dzięki Alix Axel, skróciłem Kod (tylko 100b !) i używane include zamiast require w przypadku, gdy masz różne strategie autoloadingu dla starych bibliotek (a następnie różne autoloadery w stosie autoload spl...).

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

Jeśli chcesz go skrócić / poprawić, użyj tego gist .

 28
Author: Adrien Gibrat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:23

Dokument specyfikacji PSR-0 ma przykładową kompatybilną funkcję automatycznego ładowania, która jest już dość krótka:

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

Jego użycie jest dość proste:

spl_autoload_register('autoload');

Jego wadą jest to, że należy skonfigurować katalogi bazowe, na których działa dyrektywa include_path. Do obsługi hybrydowych AUTOLOADERÓW PSR - 0 opartych na semantyce SPL, następujące supportss zawierają rozszerzenia path i spl autoload:

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

Symfony2 Komponent ClassLoader ma tę zaletę, że umożliwia większą konfigurację. Można go łatwo zainstalować poprzez Pear lub Composer (symfony/class-loader na Packagist ). Jest to komponent sam w sobie, który jest używany przez wielu i dość dobrze przetestowany i obsługiwany.

 15
Author: hakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-09 11:35:22

Splclassloader wydaje się dobrym wyborem. Jest to implementacja zaproponowana przez PSR-0.

 10
Author: Crozin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 23:01:48

Dokładny odpowiednik odpowiedzi @hakre podanej , tylko krócej:

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żesz 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);
    }
}
 4
Author: Alix Axel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:36
 1
Author: db80,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-27 15:53:28

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

Dla każdego, kto korzysta z Joomla, okazuje się, że istnieje kompatybilny autoloader już wbudowany w framework, dlatego nie będziesz musiał korzystać z powyższych funkcji. W tym przypadku wystarczy wywołać metodę jloader:: registerNamespace ().... na przykład:

JLoader::registerNamespace('Solarium', JPATH_LIBRARIES . DS . 'solarium-3.2.0' . DS . 'library');
 0
Author: Gavin G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-17 06:05:13
function autoload($fullClassName) {
    $name_elems = explode('\\', $fullClassName);
    require __DIR__.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $name_elems).'.php';
}

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

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

 0
Author: Luke Wenke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 01:17:19