PHP - 最轻薄的PSR-0自动加载磁带机兼容(PHP - most lightweight p

2019-06-17 19:44发布

我有一个很小的应用程序,我需要自动加载磁带机。 我可以很容易地使用Symfony2的类加载器,但它似乎是大材小用。

是否有一个稳定的重量极轻PSR-0 autloader在那里?

Answer 1:

你问极其轻便,让我们这样做;)

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

如果你想让它更短/更好的,请使用此要点 。



Answer 2:

在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类加载器 )。 它是由许多和相当不错的测试,支持它自己的一个组成部分。



Answer 3:

SplClassLoader似乎是一个正确的选择。 这是一个实现由PSR-0提议本身。



Answer 4:

的完全等效的答案@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);
    }
}


Answer 5:

该学说的类加载器是另一个不错的选择。 你可以用它方便地安装作曲家



Answer 6:

这不是直接回答这个问题,但我发现,上述答案在独立的PHP脚本伟大的工作,但在特定的框架,如Joomla等使用时造成了问题。

对于使用Joomla的人,事实证明,已经有内置的框架兼容的自动加载,所以你不会需要使用上述功能。 在这种情况下,只需拨打JLoader :: registerNamespace()......例如:

JLoader::registerNamespace('Solarium', JPATH_LIBRARIES . DS . 'solarium-3.2.0' . DS . 'library');


Answer 7:

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



文章来源: PHP - most lightweight psr-0 compliant autoloader