草庐IT

php - Multiple Composer Autoloader 的执行顺序

coder 2024-01-02 原文

我有一个包含多个模块的项目。每个模块在其自身内部使用 Composer,并且大部分独立于其他模块。

然而,一些模块共享具有不同版本的依赖项。这些依赖项大部分是向后兼容的,并使用语义版本控制。

我想确保具有最高语义版本的依赖项优先。这将允许所有模块共享相同的依赖关系,并且这些依赖关系的向后兼容性将确保没有任何中断。

我的计划是通过控制我在各个自动加载器上调用 require_once 的顺序来实现这一点。下面的代码是一个例子,它是在实践中生成的。

require_once(__DIR__ . '/moduleA/vendor/autoload.php');
require_once(__DIR__ . '/moduleB/vendor/autoload.php');
require_once(__DIR__ . '/moduleC/vendor/autoload.php');

我所做的主要假设是,如果在另一个之前需要一个自动加载器,它将优先于后面的自动加载器。

不过我发现相反是正确的。 最后出现的自动加载器似乎优先于其他。

考虑类 Foo\MyClass 是这些模块之间共享的依赖项。我期望按照上述加载顺序,Foo\MyClass 将从 moduleA/vendor/... 中获取。

相反,它来自 moduleC/vendor/...

我可以翻转生成的顺序来解决这个问题,但我想验证 PHP 自动加载器是否有可预测的顺序。

PHP 执行 Autoloader 有顺序吗?多个 Composer 自动加载器是否会以任何方式影响这一点?

谢谢。

最佳答案

其实,你是一团糟,只是你已经从这团乱麻中走了一半,还没有看到。

你的情况不好的是你的模块可能依赖于不兼容的第三方库。您提到他们使用语义版本控制,但这仅涵盖向上兼容性,例如“如果以兼容的方式将新功能添加到旧版本,则次要版本会增加”。这意味着这个较新的版本不向后兼容!

假设模块 A 使用版本 1.0.7 的库,模块 B 使用版本 1.2.5。该库在 1.2 版中将一个新方法添加到一个类中,模块 B 正在使用该方法。模块 B 可以与模块 A 的类版本 1.0.7 一起运行吗?当然不是。您希望两个模块都以两个模块的最高兼容版本 1.2.5 运行。

如何获得?仅使用一个 Composer 自动加载器和一个中央依赖项定义。

如果您可以创建一个包含所有模块 A、B 和 C 的依赖项的 composer.json 文件,并且每个模块声明它对其他库的依赖项,Composer 将收集所有这些库,从中计算“最佳”可用版本,并创建一个自动加载器,它只会明确地加载这些库。

额外的好处:每个库只有一个版本,没有重复。只有一个自动加载器对象具有关于所有可用类的全局知识(这可以稍微优化自动加载)。

你已经完成了一半。您的每个模块都必须已经有一个本地 composer.json 来说明版本要求。请添加一个自动加载该模块本身的定义,并为其命名。然后,您可以在中央 composer.json 中引用该名称(如果存储库是私有(private)的,您可能需要添加它们),您就快完成了。如果您确实需要在定义的路径中使用这些模块,则可能需要调整路径。

但仅此而已。

然后你解决另一件事:如果模块 A 需要模块 B 的一小部分怎么办?使用 Composer,您可以声明该依赖关系以及所有库,即使您忘记安装模块 B,Composer 也会为您安装或提醒您。

关于php - Multiple Composer Autoloader 的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23647387/

有关php - Multiple Composer Autoloader 的执行顺序的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  3. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  4. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  5. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  6. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  7. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  8. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  9. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  10. ruby-on-rails - 只有当不是 nil 时才执行映射? - 2

    如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e

随机推荐