gpt4 book ai didi

php - Symfony 2 在 Controller 之间共享数据

转载 作者:行者123 更新时间:2023-12-02 00:34:45 25 4
gpt4 key购买 nike

我已经开始使用 Symfony 2 创建一个项目。我需要在所有 Controller 之间共享数据。

我添加了一个扩展 symfony\controller 的基本 Controller ,并且我的每个 Controller 都扩展了这个基本 Controller

class BaseController extends Controller

class HomeController extends BaseController

这个基本 Controller 将用于分配全局 Twig 变量之类的事情(我知道我可以在配置中执行此操作,但某些变量将从其他配置文件和数据库中获取)。

所以我认为我可以引用容器,因为 Controller 是容器感知的,但它不是我使用函数(来自构造函数)的时候。

public function __construct ()

我看到人们提到将容器作为参数传递并提到服务,但我看过但无法弄清楚。我想要实现的只是:

public function __construct (Container $container) {
$container->get('twig').addGlobal('foo');
}

最佳答案

这是 Symfony 2 新手常见的障碍。 Controller /容器问题之前已被问过数百次,因此您并不孤单(提示)。

为什么你的 Controller 构造函数代码不起作用?

首先查看vendor/symfony...FrameworkBundle/Controller/Controller.php。唔。那里没有构造函数,那么容器到底来自哪里?我们看到 Controller 扩展了 ContainerAware。这看起来很有希望。我们查看 ContainerAware(命名空间有助于查找文件所在的位置),再次发现没有构造函数。然而,有一个 setContainer 方法,因此我们可以假设在调用构造函数后将容器注入(inject)到 Controller 中。在基于依赖注入(inject)的框架中非常常见。

现在我们知道构造函数代码失败的原因了。容器尚未注入(inject)。愚蠢的设计吧?是时候采用不同的框架了?并不真地。让我们面对现实吧,必须让所有 Controller 扩展基本 Controller 只是为了设置一些 Twig 变量,这并不是最好的设计。

Symfony 在执行 Controller 操作之前执行代码的方法是创建一个 Controller 事件监听器。它看起来像这样:

namespace Cerad\Bundle\CoreBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerAware;

use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ModelEventListener extends ContainerAware implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(KernelEvents::CONTROLLER => array(
array('doTwig', 0), // 0 is just the priority
));
}
public function doTwig(FilterControllerEvent $event)
{
// Ignore sub requests
if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) return;

$this->container->get('twig')->addGlobal('foo');
}
}
// This goes in services.yml

parameters:
cerad_core__model_event_listener__class:
Cerad\Bundle\CoreBundle\EventListener\ModelEventListener

services:
cerad_core__model_event_listener:
class: '%cerad_core__model_event_listener__class%'
calls:
- [setContainer, ['@service_container']]
tags:
- { name: kernel.event_subscriber }

现在我们已经有了所需的功能,而不需要基本 Controller 类。

另请注意,可以通过事件访问 Controller 。由于 Controller 已创建,但尚未调用操作方法,因此您可以调用 Controller 方法或直接将数据注入(inject) Controller 。这很少需要。在大多数情况下,您可以向请求对象添加附加信息,然后将其注入(inject)到 Controller 的操作方法中。

一旦您对听众和服务感到满意,这确实是一个很好的设计。

关于php - Symfony 2 在 Controller 之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21875810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com