覆盖symfony第三方捆绑资源

时间:2015-10-31 20:33:15

标签: php symfony bundle

Symfony 2.7.5

问题

我试图覆盖第三方供应商文件中的类文件,以便我可以稍微扩展一下这个功能。此文件不是服务或控制器的一部分。

相当令人困惑(我不确定为什么会这样),我通过创建目录结构覆盖了FOSUserBundle的一部分,如下所示:

 src
    │   
    │
    └───FOS
        │   
        │
        ├───Model
            │   User.php
            │   Group.php
            │   ...

这使我可以更改某些FOS用户类成员的可见性。并且它允许我在没有任何其他配置的情况下执行此操作。甚至不是儿童级的设置。

目前已尝试

我已阅读this,但它只讨论基本资源。

我还阅读this,但它似乎仅适用于Resources文件夹中的控制器或任何内容。

我尝试设置一个子包,类似于上面的链接,但没有用。

我无法想到在这种情况下成功使用继承来实现我需要做的事情。由于相关文件未在供应商包本身之外引用。

问题 (编辑)的

有没有办法可以扩展/覆盖存在于这样的目录结构中的bundle类文件?我不需要触摸大部分捆绑包,但我真的需要获取此文件。这是APYDataGridBundle的摘录。

 vendor
    │   
    │
    └───APY
        │   
        │
        ├───datagrid-bundle
            │   
            │   
            ├───Grid
                |
                | .. grid.php <-- this file

2 个答案:

答案 0 :(得分:2)

您可以使用Composer的自动加载功能执行此操作。

您可能已经知道,Composer会在您第一次调用该类时自动加载包含类的PHP文件。因此,您不必一直使用require语句。

要实现您的目标,只要调用APY\DataGridBundle\Grid\Grid,您就可以“欺骗”自动加载器加载不同的文件。

如何做到

composer.json中应该有这样的部分:

"autoload": {
    "psr-4": {
        "": "src/"
    }
},

这将告诉Composer您的类位于src/目录中。但由于APYDataGridBundle已在 composer.json中定义了更具体的命名空间路径,因此自动加载器永远不会查看您的文件。

如果您更改此块:

"autoload": {
    "psr-4": {
        "": "src/"
    },
    "classmap": ["src/APY/DataGridBundle/Grid/Grid.php"]
},

Composer将分析文件Grid.php并查找其中的类。然后它将创建一个类映射,以便每当调用其中的类时,它甚至会在检查PSR-0或PSR-4命名空间路径之前知道要加载哪个文件。

所以基本上,你告诉它文件的路径是以更高的优先级,所以首先加载它。

当然,您甚至不必将命名空间与目录结构相匹配,如果对您更好,您也可以执行src/replacements/grid.php之类的操作。只需确保文件中的namespace声明是正确的。

编辑:更改composer.json后,您必须执行composer dump-autoload,以便根据新配置生成新的自动加载文件。

答案 1 :(得分:1)

通常,您只能在以下两种情况之一中覆盖捆绑中的类:

  • 如果symfony定义了一种查找这些类的通用方法,那么只需在目录中放入一个新类就可以覆盖它们。例如,控制器会发生这种情况。
  • 如果捆绑包通过在其服务定义中使用参数来加载此类。在这种情况下,您可以通过在配置文件
  • 中设置此参数来覆盖它

在您的情况下,您很幸运,此捆绑包通过其services.xml文件中定义的参数加载此类,因此您可以通过覆盖config.yml文件中的此参数来提供自己的类:

# app/config/config.yml
parameters:
    grid.class: your own class, for example AppBundle/Grid/Grid

如果将来你发现你需要覆盖一个类并且不能通过这些方法之一来完成,你可以随时创建自己的bundle分支,尽管这很难以维护,所以我只会在你找不到其他替代方案时推荐它