首页 文章

覆盖symfony第三方捆绑资源

提问于
浏览
0

Symfony 2.7.5

Problem

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

相当容易混淆(通过创建目录结构,如下所示,'m not sure why this worked), I'已经过度使用了 FOSUserBundle 部分:

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

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

Tried so far

我读过this,但它只讨论基本资源 .

我也读过this,但它似乎只适用于控制器或 Resources 文件夹中的任何内容 .

我已经尝试设置一个子包,类似于上面的链接但无济于事 .

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

Question (已编辑)

有没有办法可以扩展/覆盖存在于这样的目录结构中的bundle类文件?我不需要触及很多捆绑包,但我真的需要得到这个文件 . 这是APYDataGridBundle的摘录 .

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

2 回答

  • 1

    您可以使用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 ,以便根据新配置生成新的自动加载文件 .

  • 2

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

    • 如果symfony定义了一种查找这些类的通用方法,那么只需在目录中放置一个新类就可以覆盖它们 . 例如,控制器会发生这种情况 .

    • 如果bundle使用其服务定义中的参数加载此类 . 在这种情况下,您可以通过在配置文件中设置此参数来覆盖它

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

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

    如果将来你发现你需要覆盖一个类并且不能通过这些方法之一来完成,你可以随时创建自己的bundle分支,虽然这很难以维护,所以我只建议如果你找不到其他选择

相关问题