如何管理依赖项自动加载 [英] How to manage dependency autoloading

查看:70
本文介绍了如何管理依赖项自动加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

构建库时,我总是提供 类,用于处理库的自动加载.自动装带器的注册方式如下:

When building a library I always provide an Autoloader class that handles autoloading for the library. The autoloader is registered like this:

require_once 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php';
PHPParser_Autoloader::register();

如果我的库依赖于另一个库,我不确定该如何处理.假设PHPParser依赖于PHPLexer.现在,使用库时,需要编写:

I'm not sure though how to handle it if my library depends on another library. Imagine that PHPParser depends on a PHPLexer. Now when using the library one would need to write:

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();

如果存在多个依赖关系,或者这些依赖关系本身具有依赖关系,则会很快变得混乱.

If there are more than just one dependency or the dependencies have dependencies themselves, this can get messy quickly.

所以一个人应该如何处理依赖项自动加载?

我曾经想到的一个想法是,库也应该对其依赖项进行自动加载,但这感觉并不对.另一个想法是完全不提供自动装带器,并假定人们使用UniversalClassLoader.但这似乎也不正确.

One idea I had was that the library should handle autoloading for it's dependencies too, but that just doesn't feel right. Another idea would be to not provide an autoloader at all and assume that people use the UniversalClassLoader. That though doesn't seem right either.

推荐答案

好,有几种方法可以解决此问题,每种方法各有利弊:

Well, there are a few ways to solve this problem, each with their own pros and cons:

  1. 对所有库使用通用的PSR-0自动加载器,并在初始化时仅注册另一个项目的位置.

  1. Use a common PSR-0 autoloader for all the libraries, and just register the location of the other project when initializing it.

  • 优势:
  1. 非常容易实现
  2. 使用相同的代码,因此只能使用一个自动加载器
  3. 您可以在应用程序引导文件中注册所有路径,因此所有库自动加载都在一个位置定义

  • 缺点

  • Disadvantages

    1. 要求所有库都实现与PSR-0兼容的文件结构
    2. 由于应用程序引导程序需要对应用程序中的所有内容(包括每个单独的库)进行引导,因此稍微降低了抽象级别.
    3. 将库的文件结构紧密耦合到您的自动加载器(如果一个库实现了一个冲突的新文件,即使他们的自动加载器起作用,它也会破坏您的自动加载器)

  • 为每个库定义一个自定义自动加载器.

    Define a custom autoloader for each library.

    • 优势
    1. 非常容易实现.
    2. 在库中保留库自动加载的语义.
    3. 由于责任分工,代码更易于维护

  • 缺点

  • Disadvantages

    1. 引导文件中有很多硬编码的类(虽然没什么大不了的)
    2. 性能,因为自动加载的类必须通过多个自动加载器
    3. 泄漏抽象级别,因为库可能需要更多的精力来进行引导,而不仅仅是自动加载

  • 为每个库(最好是由库提供)执行bootstrap.php

    Implement a bootstrap.php for each library (preferably provided by the library)

    • 优势
    1. 实施起来很简单.
    2. 在库中保留库自动加载的语义
    3. 由于关注点分离,代码更好
    4. 在不使应用程序的其他部分模糊的情况下,能够定义简单的库引导代码的能力

  • 缺点

  • Disadvantages

    1. 仍然需要require_once '/path/to/lib/dir/bootstrap.php';进行初始化
    2. 性能(由于与第二种解决方案相同的原因)
    3. 大多数3pd库未实现引导文件,因此您可能必须维护一个.
    1. Still require a require_once '/path/to/lib/dir/bootstrap.php'; to initialize
    2. Performance (for the same reason as the 2nd solution)
    3. Most 3pd libraries do not implement a bootstrap file, so you may have to maintain one.

  • 我个人使用第三个选项.例如, bootstrap.php文件我的CryptLib库.要初始化它,只需调用引导程序即可.您也可以使用任何PSR-0自动加载器,而不必调用bootstrap.php,它将正常工作.但是,使用bootstrap选项,如果我添加了需要在启动时进行自我注册的功能,则可以将其添加到bootstrap.php文件中,然后它将自动执行(而不是告诉用户他们需要执行"x,y" ,z(启动时))...

    Personally, I use the third option. An example is the bootstrap.php file in my CryptLib library. To initialize it, just call bootstrap. You could also use any PSR-0 autoloader and just not call bootstrap.php, and it will work just fine. But with the bootstrap option, if I added functionality which needed to register itself at startup, I could just add it to the bootstrap.php file and it would automatically be executed (rather than telling users that they will need to do "x, y, z" on startup)...

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

    With respect to the universal class loader option that you mentioned (calling spl_autoload_register() with no arguments), I personally don't like that option. First of all, it lowercases the classname (which is in violation of PSR-0, and I don't like it. I have gotten used to case sensitive class -> path mapping, and actually prefer it that way now). Secondly, it always uses relative paths, so it will defeat most opcode caches. There are other issues, but those are the big ones...

    这篇关于如何管理依赖项自动加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆