【问题标题】:How to make a Symfony 2 bundle with an optional dependency?如何制作带有可选依赖项的 Symfony 2 捆绑包?
【发布时间】:2012-11-27 06:49:21
【问题描述】:

假设您的包使用一些 RESTful 服务并且可以与两个不同的 PHP HTTP 客户端一起使用:guzzle/guzzle 以及kriswallsmith/Buzz。因为它使用适配器和接口。

如何将此依赖项定义为可选?你会做这样的事情吗,例如在编译器传递中?

if(!is_file('/path/to/guzzle') && !is_file('/path/to/buzz')) {
    throw new \RuntimeException('You need to install guzzle or Buzz browser.');
}

这是为包定义可选依赖项的正确方法吗?

【问题讨论】:

    标签: symfony symfony-2.1 composer-php


    【解决方案1】:

    首先,您不会像上面那样做,主要是因为检查文件是否存在于某个路径将不起作用。如果用户将它们安装在其他地方(无论出于何种原因)并设法获得正确的命名空间怎么办?

    我的第一个问题是您为什么希望用户选择。有什么区别吗?用户是否甚至能够决定使用哪个客户端。例如,当我使用资产时,我当然必须决定要使用哪些过滤器,因为它们对发生的事情有很大的影响(例如,如果我有 scss 文件,那么更少的过滤器是无用的)。

    还有其他问题,例如用户必须自己管理依赖项。有时这是值得的,有时是不值得的。

    现在,如果您决定让用户选择,我会选择一个配置选项,让用户通过字符串 guzzle 或字符串蜂鸣。也许有一个默认值。

    在您的包中,您尝试根据此配置创建对象。你可以用 try catch 块包围它来捕捉丢失的依赖项或查看某个类是否可用。如前所述,您不会测试某个文件的存在,而是使用 php 函数class_exists 测试某个类的存在。你的测试应该在你真正想要使用的一个或多个类上。

    【讨论】:

    • 我想强调对这个选择有用性的质疑。如果没有 HTTP 客户端,您的模块可能无法工作,因此这两个依赖项都不是真正可选的。您至少需要解决一个依赖项。
    • 谢谢。正如@Sven 所建议的那样,捆绑包至少需要一个依赖项。如果你在这方面想得更好,你为什么要强迫用户安装 - 比如说 guzzle - 如果他已经嗡嗡作响并且捆绑可以与后者一起使用?无论如何,我将采用配置方式,传递服务(浏览器)并使用 instanceof 运算符进行检查。
    • 您的库显然不支持我选择的 HTTP 客户端,因此我必须安装您的任何一个依赖项。应该是哪一个,为什么?我不会扩展您的图书馆来使用我的图书馆,也不会进入研究模式来了解您建议的客户中哪个更好。我什至可能不会对为什么您的图书馆更喜欢一个客户而不是另一个客户的细节感到困扰。但是我仍然可以做出选择,而且它不能开箱即用。底线:此时我质疑用户选择的有用性,但讨论它意味着讨论您的库设计决策。
    • @Sven 有趣的一点。你觉得让用户选择http客户端没用吗?
    • 我认为用户无法决定哪个可能的替代方案“更好”。要么他对使用他已经使用的那个的可能性感到惊讶,但问题仍然是其他替代方案是否会更好。作为图书馆供应商,您应该知道哪个客户端更好。除非 PHP 库就通用任务的通用接口达成一致,因此使 Composer 选项定义对虚拟“http 客户端”包的依赖项实际上有用,否则用户无法做出明智的选择 - 所以是的,这个功能实际上没用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2013-06-03
    相关资源
    最近更新 更多