如何向symfony会话添加额外的包

2o7dmzc5  于 2022-11-16  发布在  其他
关注(0)|答案(3)|浏览(142)

symfony会话我想多加一个包。
我在编译器传递中这样做:

public function process(ContainerBuilder $container)
{   
    $bag = new AttributeBag("my_session_attributes");

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

但我收到异常消息:
如果参数是对象或资源,则无法转储服务容器。
下面是跟踪堆栈:
1.在XmlDumper.php的第379行
1.在XmlDumper.php第328行中的XmlDumper::phpToXml(对象(属性包))
1.在XmlDumper.php第94行中的XmlDumper-〉convertParameters(数组(对象(属性包)),'参数',对象(DOMElement))
1.在XmlDumper.php的第183行中,在XmlDumper-〉addMethodCalls(数组('registerBag',数组(对象(属性袋))),对象(DOMElement))中找到一个数组(数组('registerBag',数组(对象(属性袋))),对象(DOMElement))
1.在XmlDumper.php第272行中的XmlDumper-〉addService(对象(定义),'会话',对象(域元素))
1.在XmlDumper.php第52行中的XmlDumper-〉addServices(对象(DOMElement))
1.在容器构建器调试转储密码. php第34行中的XmlDumper-〉dump()
1.在Compiler.php第104行中的ContainerBuilderDebugDumpPass-〉进程(对象(ContainerBuilder))
1.在编译器-〉编译(对象(ContainerBuilder))在ContainerBuilder.php第598行
1.在Kernel.php第514行中的ContainerBuilder-〉compile()
1.在Kernel.php第133行中的内核-〉初始化容器()
1.在Kernel.php第182行中的Kernel-〉 Boot ()
1.在内核-〉handle(对象(请求))在app_dev. php第29行
如果我不能在服务定义中传递对象参数,我应该如何添加新包?

k10s72fa

k10s72fa1#

好的,就在发布问题后,我有一个想法,我认为这是一个变通办法,但它的工作。
AttributeBag也必须注册为服务:

public function process(ContainerBuilder $container)
{   
    $bagDefinition = new Definition();
    $bagDefinition->setClass(AttributeBag::class);
    $bagDefinition->addArgument("my_session_attributes");
    $bagDefinition->addMethodCall("setName", ["my_session_attributes"]);
    $bagDefinition->setPublic(false);
    $container->setDefinition("my_session_attributes_service", $bagDefinition);

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

kgsdhlau2#

这件事在doc中并不清楚,你的例子帮助了一点,但我认为有一个更干净的方法来添加一个包到symfony会话,这里是我所做的(symfony 4+)
添加一个bag类,例如你可以扩展AttributeBag一

namespace App\Tracking;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;    

class TrackingBag extends AttributeBag
{
    public function __construct(string $storageKey = 'trackings')
    {
        parent::__construct($storageKey);
        $this->setName($storageKey);
    }
}

然后添加CompilerPass

public function process(ContainerBuilder $container)
{
    $container->getDefinition("session")->addMethodCall(
        "registerBag",
        [new Reference('App\\Tracking\\TrackingBag')]
    );
}

那你就可以在小枝里这样用了

{{ app.session.bag('trackings').all }}

我仍然相信有更干净的方式,但这是唯一一个为我工作。

gijlo24d

gijlo24d3#

另一种方法是通过EventListener添加新的AttributeBag。
大概是这样的:

<?php
 
namespace App\EventListener;
 
use Symfony\Component\HttpKernel\Event\RequestEvent; 
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
 
class AddSessionAttributeBagListener
{
    
    /**
     * @param RequestEvent $event
     */
    public function onKernelRequest(RequestEvent $event)
    {
        if (!$event->isMainRequest()) {
            return;
        }

        $session = $event->getRequest()->getSession();
        $bag = new AttributeBag('metrics');
        $bag->setName('metrics');
 
        $session->registerBag($bag);
    }
}

注册事件侦听器时,设置优先级以确保在正确的时间执行

app.event_listener.add_session_attribute_bag:
        class: App\EventListener\AddSessionAttributeBagListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 127}

相关问题