【发布时间】:2022-10-05 06:49:47
【问题描述】:
Symfony 5.4 版和 PHP 7.4 版。*
在一个普通的 Symfony 项目中,我可以创建一个带有路由(注释)的控制器并且它工作正常。现在我创建了一个包,我通过 Composer 将它放入一个测试项目中。在这个包中,我创建了一个带有方法和路由(注释)的控制器。
当我使用 debug:router 时,未显示捆绑包的路由。我不知道如何配置这个包以便能够在它所在的任何项目上使用控制器路由。
我可以访问 Helper 类,但我不知道如何将控制器与路由一起使用。
捆绑包内的示例:在我的包中,我有一个控制器,它呈现一个基本的树枝模板:
<?php
namespace MyWork\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class BundlePageController extends AbstractController
{
/**
* @Route("/bundle_index", name="bundle_index")
*
* @return Response
*/
public function index(): Response
{
return $this->render('bundle_page.html.twig');
}
}
当我找到的解决方案说,我必须在路由器conf中绑定它。但它没有用。我在我的包中创建了一个 routes.yml,我的想法是从将使用该包的项目中将这个 routes.yml 导入到 routes.yml 中。但我不知道参数/命名,基本上我不知道该放什么。
我也尝试过使用 symfony 文档,但我仍在苦苦挣扎。
我是否必须将此控制器作为服务加载到 service.yml 中?我有点迷路,任何帮助表示赞赏。
编辑:我在这里找到了一个帖子Symfony 5 Reusable Bundles controller has no container set, did you forget to define it as a service subscriber
在这里,控制器被添加到服务配置文件和路由配置文件中。我会尝试使用这个。
编辑:现在我添加了以下内容
捆绑服务 xml
<service id="mywork_mybundle.controller.bundle_page_controller" class="MyWork\MyBundle\Controller\BundlePageController" public="true"/>
<service id="MyWork\MyBundle\Controller\BundlePageController" alias="mywork_mybundle.controller.bundle_page_controller"/>
捆绑路由 xml
<route id="mywork_mybundle_bundle_page_controller" path="/bundle-page" controller="mywork_mybundle.controller.bundle_page_controller"/>
现在我必须弄清楚如何在项目中进行这项工作。
编辑:Route 现在显示在 debug:router 但出现错误
我已将 routes.xml 更改为 yaml,因为在项目 yaml 文件中导入它时遇到问题。所以现在在包中我有这个 routes.yaml 文件:
show_list:
path: /bundle/page/list
controller: MyWork\MyBundle\Controller\BundlePageController::list
但是,当我尝试访问此路线时,出现以下错误 URI“/bundle/page/list”的控制器不可调用:控制器“MyWork\MyBundle\Controller\BundlePageController”无法从容器中获取,因为它是私有的。您是否忘记使用“controller.service_arguments”标记服务?
这是否意味着因为我将 routes.xml 更改为 yaml 而无法读取 service.xml?如前所述,服务包含具有 true 的公钥。所以它应该是公开的。我不知道是什么导致了这里的问题。
编辑:现在在捆绑服务 xml 中,我创建了这一行:
<service id="Symfony\Bundle\FrameworkBundle\Controller\AbstractController">
<tag name="controller.abstract_controller"/>
</service>
并将它作为我的控制器的参数
<service id="mywork_mybundle.controller.bundle_page_controller" class="MyWork\MyBundle\Controller\BundlePageController" public="true">
<argument type="service" id="controller.abstract_controller"/>
</service>
<service id="MyWork\MyBundle\Controller\BundlePageController" alias="mywork_mybundle.controller.bundle_page_controller"/>
我的想法是,也许我必须先加载抽象控制器服务并将其提供给我的控制器。但老实说,我不知道...
现在我得到“...mycontroller...”没有设置容器,您是否忘记将其定义为服务订阅者?
【问题讨论】:
-
我发现查看 Symfony 的 Web Profiler Bundle 来设置路由和控制器很有用。是的,您通常确实希望将控制器定义为服务,但另一方面,通常建议避免在捆绑包中自动装配,这样可能会有点棘手。
-
哎呀。看起来你的问题增加了。您的 yaml/xml 问题的答案是否定的,如果您使用 routes.yaml 和 services.xml 并不重要。但是,您也可以考虑将捆绑服务转移到 yaml。至少在你让事情正常工作之前。您的新路由应该使用控制器的服务 ID(mywork. 等)而不是控制器类名,并摆脱该控制器别名。
-
您的页面控制器是否扩展 AbstractController 因为这也需要一些额外的位。
-
@Cerad 是的,控制器扩展了 AbstractController 它与示例中显示的几乎相同。
-
请参阅本文的结尾:github.com/symfony/symfony/discussions/44628 通常,您不应该在捆绑包中使用 AbstractController,但它确实没有害处。一旦你注入了服务定位器(又名容器),那么你至少会更进一步。