我正在使用Codeigniter和Composer。其中一个要求是PHPExcel。现在我需要在其中一个类中更改一个函数。应该做什么最好的策略?我应该更改供应商文件夹中的代码吗?如果是这样,如何在所有实例中维护更改?如果不是,我如何覆盖该特定类。虽然我提到了PHPExcel,但我想要一个通用的解决方案。
我不确定这是否是这个问题的正确论坛。如果不是我将删除此。如果需要更多细节,请告诉我。
谢谢。
答案 0 :(得分:30)
在composer.json中,在[“autoload”] [“psr-4”]下,添加一个以namespace作为键的路径,并将路径作为值:
{
"autoload": {
"psr-4": {
"BuggyVendor\\Namespace\\": "myfixes/BuggyVendor/Namespace"
}
}
}
复制要在该路径下覆盖的文件(保留子命名空间目录结构)并在那里编辑它们。它们将优先于库包的原始“类路径”而被选中。看起来以这种方式添加到composer.json的namespace->路径映射在被必需的包添加之前被考虑。注意:我只是尝试了它并且它有效,但我不知道它是否是预期的功能或可能的陷阱。
编辑:发现了一个问题。有时,当您随后需要另一个包含composer require vendor/package
的包时,您将“丢失”覆盖。如果发生这种情况,您必须手动发出composer dump-autoload
。这将恢复正确的自动加载顺序,以兑现您的覆盖。
答案 1 :(得分:5)
还有一个选择。 如果你需要重写唯一的类,你可以在composer.json中使用files这样
"autoload": {
"files": ["path/to/rewritten/Class.php"]
}
因此,如果您想重写类Some\Namespace\MyClass
,请将其置于此
#path/to/rewritten/Class.php
namespace Some\Namespace;
class MyClass {
#do whatever you want here
}
每个请求时,编辑器都会将该文件加载到内存中,因此在使用Some\Namespace\MyClass
时,将使用path/to/rewritten/Class.php
的实现。
答案 2 :(得分:0)
在我的autoload
的{{1}}部分中添加最后两行,这对于我只想覆盖composer.json
中的一个文件是很有效的目录:
vendors
请记住,"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"exclude-from-classmap": ["vendor/somepackagehere/blah/Something.php"],
"files": ["app/Overrides/Something.php"]
},
中的名称空间必须与app/Overrides/Something.php
中的原始名称相匹配。
在编辑vendor/somepackagehere/blah/Something.php
之后,请记住要运行composer dump-autoload
。
答案 3 :(得分:-3)
更改现有类是针对OOP和SOLID原则(特定于修改原则的Open to extension / Closed)。因此,这里的解决方案不是直接更改代码,而是扩展代码以添加功能。
在一个理想的世界中,你永远不应该改变你不拥有的代码。 事实上,使用编辑器是不可能的,因为在更新依赖项时,您的更改将被覆盖。
在您的情况下,解决方案是在应用程序级别创建一个类,并扩展您要更改的类(在库级别)以覆盖您的代码。如果你不知道怎么做,请查看用PHP扩展课程。
然后通常,你加载你的类而不是他们的类,这样,你在功能上添加你的功能,并且在更新的情况下,没有任何中断(如果没有更新的中断)。