У меня есть крошечное приложение, для которого мне нужен автозагрузчик. Я мог бы легко использовать загрузчик классов symfony2, но он кажется излишним.
Есть ли стабильный чрезвычайно легкий psr-0 автозагрузчик там?
Вы просите чрезвычайно легкий, давайте сделаем это;)
Тимоти Борончик написал хороший минимальный автозагрузчик 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 ] с коротким кодом @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 является самым коротким!
Давайте использовать стабильный и чрезвычайно легкий (175b!) Файл автозагрузчика:
<?php spl_autoload_register(function ($c){preg_match('/^(.+)?([^\\\\]+)$/U',ltrim($c,'\\'),$m);require str_replace('\\','/',$m[1]).str_replace(['\\','_'],'/',$m[2]).'.php';});
Может быть, я сумасшедший, но вы спросили о крайности, нет?
EDIT: благодаря Alix Axel, я сократил код (только 100b!) И использовал include вместо требования, если у вас есть стратегия автозагрузки для старых библиотек (а затем различные автозагрузчики в стеке автозагрузки) ….
<?php spl_autoload_register(function($c){@include preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';});
Если вы хотите сделать это короче / лучше, используйте этот смысл .
В документе спецификации PSR-0 имеется примерная совместимая функция автозагрузчика, которая уже довольно короткая:
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, следующая поддержка включает в себя пути и расширения автозагрузки splash:
$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 ClassLoader имеет преимущество, позволяющее больше конфигурировать здесь. Вы можете легко установить его через Pear или Composer ( symfony / class-loader на Packagist ). Это компонент на своем собственном, который используется многими и достаточно хорошо протестирован и поддерживается.
SplClassLoader кажется правильным выбором. Это реализация, предложенная самой PSR-0 .
Точный эквивалент ответа @hakre предоставлен , короче:
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); } }
Классный загрузчик доктрины – еще один хороший выбор. Вы можете легко установить его с помощью композитора
Это не прямой ответ на вопрос, но я обнаружил, что вышеупомянутые ответы отлично работали на автономных скриптах PHP, но вызывали проблемы при использовании в определенных рамках, таких как Joomla.
Для всех, кто использует Joomla, выясняется, что в инфраструктуру уже встроен совместимый автозагрузчик, поэтому вам не нужно использовать вышеуказанные функции. В этом случае просто вызовите JLoader :: registerNamespace () …. например:
JLoader::registerNamespace('Solarium', JPATH_LIBRARIES . DS . 'solarium-3.2.0' . DS . 'library');
function autoload($fullClassName) { $name_elems = explode('\\', $fullClassName); require __DIR__.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $name_elems).'.php'; }
Это даже поддерживает такие вещи, как: $ transformerContstraint = new \ Recurr \ Transformer \ Constraint \ AfterConstraint (новый DateTime ());
Просто поместите его в /vendor/Recurr/Transformer/Constraint/AfterConstraint.php