Vincent PHILIPPE
Vincent PHILIPPE

Reputation: 1191

Circular reference detected for service "session", path: "session -> session.flash_bag -> session"

I have read about Namespaced Attributes. I try to use this feature :

#src/Controller/CartController.php
public function addProduct(int $cart_id, int $product_id, Request $request, SessionManager $sessionManager)
{
   $session = new Session(new NativeSessionStorage(), new NamespacedAttributeBag());
   $session->set("cart_$cart_id/product_$product_id", $request->get('selected_product_qty'));
   dump($session);
   die();
}

It work well.

So as an improvement, I want to override the session services, so it'll use namespacedattributebag everywhere and it use Depency Injection instead of coupling Session service into addProduct function.

To do this I edit my services.yaml

#config/services.yaml
    session:
        public: true
        class: Symfony\Component\HttpFoundation\Session\Session
        arguments: ['@session.storage', '@session.namespacedattributebag']

    session.namespacedattributebag:
        class: Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag

And then I update CartController :

public function addProduct(int $cart_id, int $product_id, Request $request, Session $session)
{
   $session->set("cart_$cart_id/product_$product_id", $request->get('selected_product_qty'));
   dump($session);
   die();
}

Now I got the following error message :

Circular reference detected for service "session", path: "session -> session.flash_bag -> session".

This error should have been solved in this issue : #36261 It have been discussed here.

But for me the problem still present... (I am using Symfony 5.1)

Upvotes: 4

Views: 876

Answers (1)

Vincent PHILIPPE
Vincent PHILIPPE

Reputation: 1191

I can't provide more explanation (unfortunately) but if this problem occurs, you have to explicitely define the third (and optionnal parameter) of Session constructor :

#config/services.yaml
session:
    public: true
    class: Symfony\Component\HttpFoundation\Session\Session
    arguments: ['@session.storage', '@session.namespacedattributebag', '@session.flash_bag']

session.namespacedattributebag:
    class: Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag

I think this is because of the following code :

#src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/SessionPass.php
foreach ($container->getDefinition('session')->getArguments() as $v) {
    if (!$v instanceof Reference || !isset($bags[$bag = (string) $v]) || !\is_array($factory = $bags[$bag]->getFactory())) {
        continue;
    }

    if ([0, 1] !== array_keys($factory) || !$factory[0] instanceof Reference || 'session' !== (string) $factory[0]) {
        continue;
    }

    if ('get'.ucfirst(substr($bag, 8, -4)).'Bag' !== $factory[1]) {
        continue;
    }
    $bags[$bag]->setFactory(null);
}

You'll see that if you debug it :

dump($bags);
foreach($container->getDefinition('session')->getArguments() as $v){...}
dump($bags);

And having your config like this :

#config/services.yaml
...
arguments: ['@session.storage', '@session.namespacedattributebag', '@session.flash_bag']
...

You'll notice that debug show :

"session.flash_bag" => Symfony\Component\DependencyInjection\Definition {#2253 ▼
    -class: "Symfony\Component\HttpFoundation\Session\Flash\FlashBag"
    -file: null
    -factory: array:2 [▶]

For the input services Definition of flash_bag And then in output (Second dump()) :

"session.flash_bag" => Symfony\Component\DependencyInjection\Definition {#2253 ▼
    -class: "Symfony\Component\HttpFoundation\Session\Flash\FlashBag"
    -file: null
    -factory: null

The factory parameter is null.

So I guess that in this case flash_bag object isn't created, and so, there is no Circular reference...

I can't explain it more.

Plus, someone from Symfony staff said : @warslett commented on 28 Mar

@ekosogin you don't actually need the @session.flash_bag parameter on there. You should be able to do this:

session:
    class: Symfony\Component\HttpFoundation\Session\Session
    arguments:
        - '@session.storage'
        - '@Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag'
Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag:
~```

But actually, I think this is wrong as it'll not work if you don't put the @session.flash_bag parameter as he say.

Hope it'll help.

Upvotes: 3

Related Questions