覆盖 symfony 3rd 方包资源
override symfony 3rd party bundle resource
Symfony 2.7.5
问题
我正在尝试覆盖第 3 方供应商文件中的 class 文件,以便我可以稍微扩展功能。此文件不是服务或控制器的一部分。
相当令人困惑(我不确定为什么会这样),我通过创建如下目录结构覆盖了 FOSUserBundle
的一部分:
src
│
│
└───FOS
│
│
├───Model
│ User.php
│ Group.php
│ ...
这让我可以更改某些 FOS 用户 class 成员的可见性。它使我无需任何其他配置即可完成此操作。甚至不是儿童-class 设置。
目前已尝试
我看过this,但它只讲基本资源。
我也读过 this,但它似乎只适用于控制器或 Resources
文件夹中的任何内容。
我试过设置一个子包,类似于上面的 link 但无济于事。
我想不出在这种情况下成功使用继承来完成我需要做的事情的方法。由于相关文件未在供应商捆绑包本身之外引用。
问题(已编辑)
有什么方法可以 extend/override 一个包 class 文件,放在这样的目录结构中?我不需要接触太多的包,但我真的需要得到这个文件。这是摘自 APYDataGridBundle.
vendor
│
│
└───APY
│
│
├───datagrid-bundle
│
│
├───Grid
|
| .. grid.php <-- this file
您可以使用 Composer 的自动加载功能来完成此操作。
Composer,您可能已经知道,每当您首次调用 class 时,它会自动加载包含 class 的 PHP 文件。所以你不必一直使用 require
语句。
为了实现您的目标,您可以“欺骗”自动加载器在每次调用 APY\DataGridBundle\Grid\Grid
时加载一个 不同的 文件。
怎么做
在你的 composer.json
中应该有这样一个部分:
"autoload": {
"psr-4": {
"": "src/"
}
},
这将告诉 Composer 您的 classes 在 src/
目录中。但是由于 APYDataGridBundle 已经在 他们的 composer.json
中定义了一个更具体的命名空间路径,自动加载器将永远不会查看您的文件。
如果像这样更改块:
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": ["src/APY/DataGridBundle/Grid/Grid.php"]
},
Composer 将分析文件 Grid.php
并在其中查找 classes。然后它将创建一个 class 映射,以便每当调用其中的 class 时,它甚至在检查 PSR-0 或 PSR-4 命名空间路径之前就知道要加载哪个文件。
所以基本上,您是在告诉它优先级更高的文件的路径,以便它首先加载。
当然,你甚至不必将命名空间与你的目录结构相匹配,你也可以做类似 src/replacements/grid.php
的事情,如果这对你来说更好的话。只需确保文件中的 namespace
声明是正确的。
编辑:更改 composer.json
后,您必须执行 composer dump-autoload
,以便根据新配置生成新的自动加载文件。
一般来说,您只能在以下两种情况之一中覆盖捆绑包中的 class:
- 如果 symfony 已经定义了一种通用的方法来查找这些 classes,这样您就可以通过在目录中放置一个新的 class 来覆盖它们。例如,控制器会发生这种情况。
- 如果捆绑包通过在其服务定义中使用参数来加载此 class。在这种情况下,您可以通过在配置文件中设置此参数来覆盖它
在你的情况下,你很幸运,这个包通过在其 services.xml 文件中定义的参数加载这个 class,所以你可以通过覆盖这个参数来提供你自己的 class您的 config.yml 文件:
# app/config/config.yml
parameters:
grid.class: your own class, for example AppBundle/Grid/Grid
如果将来您发现需要重写 class 并且无法通过这些方法之一完成,您可以随时创建自己的捆绑包分支,尽管这很痛苦并且很难维护,所以我只会在你找不到其他选择的情况下推荐它
Symfony 2.7.5
问题
我正在尝试覆盖第 3 方供应商文件中的 class 文件,以便我可以稍微扩展功能。此文件不是服务或控制器的一部分。
相当令人困惑(我不确定为什么会这样),我通过创建如下目录结构覆盖了 FOSUserBundle
的一部分:
src
│
│
└───FOS
│
│
├───Model
│ User.php
│ Group.php
│ ...
这让我可以更改某些 FOS 用户 class 成员的可见性。它使我无需任何其他配置即可完成此操作。甚至不是儿童-class 设置。
目前已尝试
我看过this,但它只讲基本资源。
我也读过 this,但它似乎只适用于控制器或 Resources
文件夹中的任何内容。
我试过设置一个子包,类似于上面的 link 但无济于事。
我想不出在这种情况下成功使用继承来完成我需要做的事情的方法。由于相关文件未在供应商捆绑包本身之外引用。
问题(已编辑)
有什么方法可以 extend/override 一个包 class 文件,放在这样的目录结构中?我不需要接触太多的包,但我真的需要得到这个文件。这是摘自 APYDataGridBundle.
vendor
│
│
└───APY
│
│
├───datagrid-bundle
│
│
├───Grid
|
| .. grid.php <-- this file
您可以使用 Composer 的自动加载功能来完成此操作。
Composer,您可能已经知道,每当您首次调用 class 时,它会自动加载包含 class 的 PHP 文件。所以你不必一直使用 require
语句。
为了实现您的目标,您可以“欺骗”自动加载器在每次调用 APY\DataGridBundle\Grid\Grid
时加载一个 不同的 文件。
怎么做
在你的 composer.json
中应该有这样一个部分:
"autoload": {
"psr-4": {
"": "src/"
}
},
这将告诉 Composer 您的 classes 在 src/
目录中。但是由于 APYDataGridBundle 已经在 他们的 composer.json
中定义了一个更具体的命名空间路径,自动加载器将永远不会查看您的文件。
如果像这样更改块:
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": ["src/APY/DataGridBundle/Grid/Grid.php"]
},
Composer 将分析文件 Grid.php
并在其中查找 classes。然后它将创建一个 class 映射,以便每当调用其中的 class 时,它甚至在检查 PSR-0 或 PSR-4 命名空间路径之前就知道要加载哪个文件。
所以基本上,您是在告诉它优先级更高的文件的路径,以便它首先加载。
当然,你甚至不必将命名空间与你的目录结构相匹配,你也可以做类似 src/replacements/grid.php
的事情,如果这对你来说更好的话。只需确保文件中的 namespace
声明是正确的。
编辑:更改 composer.json
后,您必须执行 composer dump-autoload
,以便根据新配置生成新的自动加载文件。
一般来说,您只能在以下两种情况之一中覆盖捆绑包中的 class:
- 如果 symfony 已经定义了一种通用的方法来查找这些 classes,这样您就可以通过在目录中放置一个新的 class 来覆盖它们。例如,控制器会发生这种情况。
- 如果捆绑包通过在其服务定义中使用参数来加载此 class。在这种情况下,您可以通过在配置文件中设置此参数来覆盖它
在你的情况下,你很幸运,这个包通过在其 services.xml 文件中定义的参数加载这个 class,所以你可以通过覆盖这个参数来提供你自己的 class您的 config.yml 文件:
# app/config/config.yml
parameters:
grid.class: your own class, for example AppBundle/Grid/Grid
如果将来您发现需要重写 class 并且无法通过这些方法之一完成,您可以随时创建自己的捆绑包分支,尽管这很痛苦并且很难维护,所以我只会在你找不到其他选择的情况下推荐它