我有一个很小的应用程序,我需要自动加载磁带机。 我可以很容易地使用Symfony2的类加载器,但它似乎是大材小用。
是否有一个稳定的重量极轻PSR-0 autloader在那里?
我有一个很小的应用程序,我需要自动加载磁带机。 我可以很容易地使用Symfony2的类加载器,但它似乎是大材小用。
是否有一个稳定的重量极轻PSR-0 autloader在那里?
你问极其轻便,让我们这样做;)
蒂莫西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]与短@Alix阿克塞尔代码 [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';});
如果你想让它更短/更好的,请使用此要点 。
在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语义,以下一个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);
};
在该Symfony2的类加载器组件必须允许更多的在这里配置的好处。 您可以通过梨或作曲(容易安装的symfony /上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 =新\ Recurr \变压器\约束\ AfterConstraint(新的DateTime());
只要把它放在/vendor/Recurr/Transformer/Constraint/AfterConstraint.php