提问人:H3lltronik 提问时间:12/3/2019 最后编辑:yiviH3lltronik 更新时间:12/6/2019 访问量:1684
从自定义捆绑包中的控制器获取配置参数
Get config parameters from controller within a custom bundle
问:
我正在尝试从配置 yaml 文件中获取一些参数,我正在执行以下操作:
namespace ExampleVendor\AdminBundle\Controller;
/**
* @Route("/", name="_home")
*/
public function index(ParameterBagInterface $params) {
$menuIcons = $this->getParameter('admin-aside-menu');
dump($menuIcons);
return $this->render('@ExampleVendorAdminBundle/index.html.twig');
}
如您所见,它只是一个打印参数的转储函数,问题是,此代码在 App\src\Controller 中的控制器中工作时有效,我的意思是在“main”应用程序 src 文件夹中,但是当我复制此代码并将其粘贴到自定义捆绑包中的控制器中时(类似于 vendor/myVendor/myBundle/src/Controller)重新加载页面时出现错误:admin-aside-menu
无法解决“ExampleVendor\AdminBundle\Controller\AdminController::index()”的参数$params,也许您忘记将控制器注册为服务或错过了用“controller.service_arguments”标记它?
我需要获取这些参数,但我不知道如何将其“注入”到我的控制器中。ParameterBagInterface
好的,所以这篇文章似乎说了如何解决这个问题,但是,由于我需要注入某些东西的控制器位于供应商文件夹的自定义捆绑包中,因此答案对我根本没有帮助
Project
|
+--AdminBundle <- My custom bundle, installed via composer as symlink
| |
| +--Controller
| | |
| | +--AdminController.php <- Heres where I want to get my parameter
| |
| +--DependencyInjection
| +--Entity
| +--Resources
| |
| +--config
| |
| +--custom.yaml <- There are my custom params
| +--services.yaml <- Heres where I should register my controller as service?
|
+--assets
|
+--bin
|
+--config
|
+--public
|
+--src
|
+--templates
|
+--vendor <- Heres my admin bundle as symlink
该文件夹是通过 composer 作为符号链接的安装程序,因此我可以在我的项目中使用它,所以知道这一点,任何人都知道我如何将参数直接注入到我的控制器中?AdminBundle
ParametersBag
这是我的custom.yaml,它保存了我的捆绑包中的参数
// AdminBundle/Resources/config/custom.yaml
parameters:
admin-aside-menu:
items:
- icon: 'Home/Chair2'
title: 'Prueba'
- icon: 'Home/Deer'
title: 'Prueba Venado'
这是依赖注入中的配置类
// AdminBundle/DependencyInjection/Configuration.php
class Configuration implements ConfigurationInterface {
public function getConfigTreeBuilder() {
$treeBuilder = new TreeBuilder('admin-aside-menu');
$treeBuilder->getRootNode()
->children()
->arrayNode('items')
->children()
->scalarNode('icon')->end()
->scalarNode('title')->end()
->end()
->end()
;
return $treeBuilder;
}
}
这是捆绑包扩展
// AdminBundle/DependencyInjection/ExampleVendorAdminExtension .php
class ExampleVendorAdminExtension extends Extension {
/**
* Loads a specific configuration.
*
* @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $configs, ContainerBuilder $container) {
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
$loader->load('custom.yaml');
$loader->load('services.yaml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
}
}
我在我的 services.yaml 中写了这个,根据 Florian 的响应将我的参数注入到我的控制器中
// AdminBundle/Resources/config/services.yaml
services:
admin-bundle.controller.admin-controller:
class: ExampleVendor\AdminBundle\Controller\AdminController
arguments:
- "%admin-aside-menu%"
它似乎在某种程度上起作用,因为当我写得不好(错别字)时,错误页面说"%admin-aside-menu%"
“你是说:'admin-aside-menu'吗?”
所以我认为它实际上正在加载我的参数,但在我的控制器中我无法“注入”它
这是控制器:
/**
* @Route(name="admin")
*
* Class AdminController
* @package ExampleVendor\AdminBundle\Controller
*/
class AdminController extends AbstractController {
public function __construct(array $adminAsideMenu) {
dump($adminAsideMenu);
}
}
但是当我运行它时,我收到此错误
URI “/admin/” 的控制器不可调用。控制器“ExampleVendor\AdminBundle\Controller\AdminController”具有必需的构造函数参数,并且容器中不存在。您是否忘记将控制器定义为服务?
答:
打开 service.yaml 然后输入类名并选择一个 ID 以通过自动布线获取它
services:
ExampleVendor\AdminBundle\Controller = '@adminbundle_thenameyouchoose'
评论
由于任何编码标准和实践,您永远不应该在供应商包中编写代码。vendor 不是您应该推送到 git 存储库中的文件夹,原因之一是静态库的过大大小实际上不属于您的项目,而且当您尝试更新您的 composer 依赖项时,这种做法会造成一团糟。您应该保持清洁并将供应商添加到 .gitignore 中。Symfony为覆盖服务提供了很好的支持,检查一下。
评论
构建自己的捆绑包并不简单。
从您与我们共享的捆绑包结构中,我可以看到您已经有了 Dependency injection 文件夹。
此文件夹应包含两个文件:
- 配置:.php
- 您的捆绑名称扩展名:.php
要注入控制器的参数应在捆绑包的配置中,因此必须完成 Configuration.php 才能添加它。(我不是这方面的专家,所以我让你自己搜索)
此外,为了在捆绑包的代码中访问您的配置,您必须将配置作为参数注入,并为您的捆绑包添加前缀。你可以在这里找到一个例子来了解如何做到这一点:https://github.com/Orbitale/CmsBundle/blob/4.x/DependencyInjection/OrbitaleCmsExtension.php
现在,在 Resources/services.yaml 中,您可以将控制器添加为服务:
services:
bundle_name.controller.your_controller:
class: Your\Controller\Namespace
arguments:
- '%bundle_key.your_parameter_name%'
这样的事情应该有效,但可能并不完全清楚。所以如果你有更多问题,我会尽力回答你。
不要犹豫,检查现有的捆绑包作为灵感来源。
---------------------- 编辑以回答 编辑 2 ----------------------
据我所知,您的捆绑配置密钥是“admin-aside-menu”?也许它应该是“admin_aside_menu”(以符合惯例)。无论如何:
是的,你快到了,但缺少一些东西。您不能直接在捆绑包的 config 中定义参数。相反,当您从应用程序中使用捆绑包时,您将在 /config/packages/admin-aside-menu.yaml 中拥有如下文件:
admin-aside-menu:
items:
- icon: 'Home/Chair2'
title: 'Prueba'
- icon: 'Home/Deer'
title: 'Prueba Venado'
这是您当前使用的捆绑包配置,它应该与您在 AdminBundle/DependencyInjection/Configuration.php 文件中定义的格式匹配。(我帮不了你,因为这不是我经常做的事情)。
您现在可以完全删除文件 AdminBundle/Resources/config/custom.yaml,因为该配置位于您的应用程序中。
然后,在扩展中,您可以获取此配置以将其注入到应用程序参数中,并带有捆绑包的前缀。如果我修改你的代码,它应该是这样的:
// AdminBundle/DependencyInjection/ExampleVendorAdminExtension .php
class ExampleVendorAdminExtension extends Extension {
/**
* Loads a specific configuration.
*
* @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load(array $configs, ContainerBuilder $container) {
$loader = new YamlFileLoader( $container, new FileLocator(__DIR__.'/../Resources/config') );
// $loader->load('custom.yaml'); not needed anymore
$loader->load('services.yaml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
// This part inject your config in parameters
foreach ($config as $key => $value) {
$container->setParameter('admin-aside-menu.'.$key, $value);
}
}
}
现在您的配置参数已设置!
最后一步,将其注入控制器:
// AdminBundle/Resources/config/services.yaml
services:
admin-bundle.controller.admin-controller:
class: ExampleVendor\AdminBundle\Controller\AdminController
arguments:
- "%admin-aside-menu.items%"
这样可以吗?
评论