覆盖使用Composer安装的库中的类的策略

SNA*_*NAG 21 php codeigniter composer-php

我正在使用Codeigniter和Composer.其中一个要求是PHPExcel.现在我需要在其中一个类中更改一个函数.应该做什么最好的策略?我应该更改供应商文件夹中的代码吗?如果是这样,如何在所有实例中维护更改?如果不是,我如何覆盖该特定类.虽然我提到了PHPExcel,但我想要一个通用的解决方案.

我不确定这是否是这个问题的正确论坛.如果不是我将删除此.如果需要更多细节,请告诉我.

谢谢.

Szc*_*ski 37

在composer.json中,在["autoload"] ["psr-4"]下,添加一个以名称空间作为键和路径作为值的条目:

{
     "autoload": {

         "psr-4": {

             "BuggyVendor\\Namespace\\": "myfixes/BuggyVendor/Namespace"
         }
     }
}
Run Code Online (Sandbox Code Playgroud)

复制要在该路径下覆盖的文件(保留子命名空间目录结构)并在那里编辑它们.它们将优先于库包的原始"类路径"而被选中.看起来以这种方式添加到composer.json的namespace-> path映射在被必需的包添加之前被考虑.注意:我只是尝试了它并且它有效,但我不知道它是否是预期的功能或可能的陷阱.

编辑:发现了一个问题.有时当您随后需要另一个包时composer require vendor/package,您将"丢失"覆盖.如果发生这种情况,您必须composer dump-autoload手动发出.这将恢复正确的自动加载顺序,以兑现您的覆盖.

  • 使用这种方法你可能会得到类似的东西:```警告:模糊的类解析,"Doctrine\Common\Collections\ArrayCollection"在"vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection"中找到. php"和"src\Doctrine\Common\Collections\ArrayCollection.php",第一个将被使用.```克服这个问题将原始类添加到排除:```"exclude-from-classmap":["vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php"]``,和然后自动加载器将解析您的覆盖类. (12认同)
  • @OlegAndreyev 只需从自动加载器中删除前一个类,以防止发生“模糊类解析”警告:`"autoload": {"exclude-from-classmap": ["vendor/path-to-file-to-ignore. php"]}`。 (2认同)

Rya*_*yan 13

当我只想覆盖目录中的一个文件时,将最后两行添加autoloadmy的部分对我composer.json有用vendors

"autoload": {        
    "classmap": [
        "database"
    ],
    "psr-4": {
        "App\\": "app/"
    },
    "exclude-from-classmap": ["vendor/somepackagehere/blah/Something.php"],
    "files": ["app/Overrides/Something.php"]
},
Run Code Online (Sandbox Code Playgroud)

请记住,其中的命名空间app/Overrides/Something.php需要匹配原始文件中的任何内容vendor/somepackagehere/blah/Something.php

composer dump-autoload编辑完后记得运行composer.json

文档:https : //getcomposer.org/doc/04-schema.md#files

  • 按预期工作! (3认同)
  • 记得运行 `composer dump-autoload` +1 (2认同)

Alb*_*bac 12

还有另一种选择。如果您需要重写唯一的类,则可以像这样使用composer.json中的文件

 "autoload": {
     "files": ["path/to/rewritten/Class.php"]
  }
Run Code Online (Sandbox Code Playgroud)

因此,如果您想重写类Some\Namespace\MyClass,请像下面这样

#path/to/rewritten/Class.php

namespace Some\Namespace;

class MyClass {
  #do whatever you want here
}
Run Code Online (Sandbox Code Playgroud)

根据每个请求,编辑器会将文件加载到内存中,因此在使用时Some\Namespace\MyClass- path/to/rewritten/Class.php将使用from的实现。