在Controller中使用Symfony AttributeBags

时间:2017-06-23 18:13:19

标签: symfony session symfony-3.2

我在这里读过有关会议的内容:

https://symfony.com/doc/current/components/http_foundation/sessions.html

如果我直接使用代码,使用Guard的Symfony登录在第一次尝试时不起作用(第一次总是失败,第二次成功)。所以我猜我必须在$this->container->get('session')使用会话。但是添加袋子会让我感到困惑。

我试过这个:

/**
 * @Route("/", name="homepage")
 */
public function indexAction(Request $request) {
    $session=$this->container->get('session');
    $cart=new AttributeBag('ShoppingCartItems');
    $session->registerBag($cart);
    $session->start();

......但它告诉我

  

会话已经开始时无法注册包。

我试过这个:

...在捆绑中:

    public function build(ContainerBuilder $container) {
        parent::build($container);
        $container->addCompilerPass(new \Website\DependencyInjection\Compiler\InjectShoppingCart());
    }

...然后是InjectShoppingCart

namespace Website\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

class InjectShoppingCart implements CompilerPassInterface {
    public function process(ContainerBuilder $container) {
        $bagDefinition = new Definition();
        $bagDefinition->setClass(AttributeBag::class);
        $bagDefinition->addArgument("ShoppingCartItems");
        $bagDefinition->addMethodCall("setName", ["ShoppingCartItems"]);
        $container->setDefinition("ShoppingCartItemsService",$bagDefinition);

        $container->getDefinition("session")->addMethodCall("registerBag",[new Reference("ShoppingCartItemsService")]);
    }
}

...我尝试使用Cargo Cult风格来自question 44723613。无论它做什么,它都不会导致属性包的注册。

无论我到目前为止尝试过什么,Guard身份验证都会中断,否则包不会被注册。不过,我希望两者兼顾,但希望不安装外部库的Megs和Megs。

这不可能是这么难。我错过了什么?

1 个答案:

答案 0 :(得分:1)

好的,我明白了。

最后,它只是我使用的示例中的一行,这让我失败了:

$bagDefinition->addArgument("ShoppingCartItems");

...必须删除。

这一切都是在编译器传递中,而不是让它这样做:

$bag = new AttributeBag('ShoppingCartItems');
$bag->setName('ShoppingCartItems');
$session->registerBag($bag);

我需要这样做:

$bag = new AttributeBag();
$bag->setName('ShoppingCartItems');
$session->registerBag($bag);

所以InjectShoppingCart最终看起来像这样:

namespace Website\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

class InjectShoppingCart implements CompilerPassInterface {
    public function process(ContainerBuilder $container) {
        $bagDefinition = new Definition();
        $bagDefinition->setClass(AttributeBag::class);
        $bagDefinition->addMethodCall("setName", ["ShoppingCartItems"]);
        $container->setDefinition("ShoppingCartItemsService",$bagDefinition);

        $container->getDefinition("session")->addMethodCall("registerBag",[new Reference("ShoppingCartItemsService")]);
    }
}