Php 如何管理依赖项自动加载

Php 如何管理依赖项自动加载,php,autoload,Php,Autoload,在构建库时,我总是提供一个类来处理库的自动加载。自动加载器的注册方式如下: require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php'; PHPParser_Autoloader::register(); 如果我的库依赖于另一个库,我不知道如何处理它。假设PHPParser依赖于PHPLexer。现在,在使用库时,需要编写: require_once 'path/to/PHP-Lexer/lib/PHPLexer/Autoloa

在构建库时,我总是提供一个类来处理库的自动加载。自动加载器的注册方式如下:

require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php';
PHPParser_Autoloader::register();
如果我的库依赖于另一个库,我不知道如何处理它。假设
PHPParser
依赖于
PHPLexer
。现在,在使用库时,需要编写:

require_once 'path/to/PHP-Lexer/lib/PHPLexer/Autoloader.php';
PHPLexer_Autoloader::register();

require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php';
PHPParser_Autoloader::register();
如果有不止一个依赖项,或者依赖项本身有依赖项,那么很快就会变得混乱

那么,如何处理依赖项自动加载呢


我的一个想法是,库也应该处理其依赖项的自动加载,但这感觉不太对。另一个想法是根本不提供自动加载器,并假设人们使用
UniversalClassLoader
。但这似乎也不正确。

添加到类构造函数

public function __construct(){
$this->Register();
}
之后,在页面上,您需要让load创建一个对象

$obj = new PHPParser_Autoloader();

如果库中的类按PSR-0约定命名,则可以对所有库使用一个自动加载器。否则,库应该提供自己的自动加载器。

好吧,有几种方法可以解决这个问题,每种方法都有各自的优缺点:

  • 对所有库使用公共PSR-0自动加载程序,并在初始化其他项目时仅注册其位置

    • 优点:
    • 实现起来非常简单
    • 使用相同的代码,因此只能使用一个自动加载器
    • 您可以在应用程序引导文件中注册所有路径,因此所有库自动加载都是在一个位置定义的
    • 缺点
    • 要求所有库实现与PSR-0兼容的文件结构
    • 由于应用程序引导需要引导应用程序内部的所有内容,包括每个库,因此会稍微泄漏抽象级别
    • 将库的文件结构与自动加载器紧密耦合(如果库实现了一个冲突的新文件,它将破坏自动加载器,即使它们的文件有效)
  • 为每个库定义自定义自动加载器

    • 优势
    • 实现起来非常简单
    • 在库中保留库自动加载语义
    • 由于职责分离,代码更易于维护
    • 缺点
    • 引导文件中有很多硬编码的类(不过没什么大不了的)
    • 由于自动加载的类必须经过多个自动加载程序,因此性能降低
    • 泄漏抽象级别,因为库可能需要比自动加载更大的努力来引导
  • 为每个库实现bootstrap.php(最好由库提供)

    • 优势
    • 实现起来非常简单
    • 在库中保留库自动加载语义
    • 由于关注点的分离,代码变得更好
    • 能够在不影响应用程序其他部分的情况下定义非平凡的库引导代码
    • 缺点
    • 仍然需要一个
      require_once'/path/to/lib/dir/bootstrap.php'初始化
    • 性能(与第二个解决方案的原因相同)
    • 大多数3pd库不实现引导文件,因此您可能需要维护一个引导文件
  • 就我个人而言,我使用第三种选择。一个例子是MyCryptLib库中的。要初始化它,只需调用bootstrap。您也可以使用任何PSR-0自动加载器,而不调用bootstrap.php,这样它就可以正常工作。但是使用bootstrap选项,如果我添加了需要在启动时注册的功能,我可以将它添加到bootstrap.php文件中,它将自动执行(而不是告诉用户在启动时需要执行“x,y,z”)


    关于您提到的通用类加载器选项(无参数调用
    spl\u autoload\u register()
    ),我个人不喜欢这个选项。首先,它将类名小写(这违反了PSR-0,我不喜欢它。我已经习惯了区分大小写的类->路径映射,实际上现在更喜欢这种方式)。其次,它总是使用相对路径,因此它将击败大多数操作码缓存。还有其他问题,但这些都是大问题…

    我的一个想法是,库也应该处理其依赖项的自动加载,但这感觉不太正确。
    -当所有供应商都支持PSR-0时,这个想法很好,我不确定这对解决依赖项问题有何帮助。你能详细说明一下吗?我同意@NikiC只需看看symfony提供的universal autoloader(请参见
    $loader->registerPrefixes
    ),因为您的PHPParser是symfony2的一部分。