I just made the migration from symfony 4.1 to 4.4 I have this error:
Argument 1 passed to App\EventListener\KernelRequestListener::__construct() must be an instance of Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage, instance of Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage given, called in C:\xampp\htdocs\chat-project-symfony\var\cache\dev\Container06Mjwya\srcApp_KernelDevDebugContainer.php on line 1130
While if you look at my KernelRequestListener
:
<?php
namespace App\EventListener;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
//..
class KernelRequestListener
{
private $tokenStorage;
/**
* KernelRequestListener constructor.
* @param TokenStorage $tokenStorage
* ...
*/
public function __construct(TokenStorage $tokenStorage/*...*/)
{
$this->tokenStorage = $tokenStorage;
//..
}
}
Here is my config/services.yaml
file:
#...
services:
#..
App\EventListener\KernelRequestListener:
arguments: [ '@security.token_storage' ]
tags:
- { name: kernel.event_listener, event: kernel.request }
- { name: kernel.event_listener, event: kernel.response }
I don't know why symfony tell me that I'm using Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage
while it's clearing written Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage
I already tried to clear the cache folder and also delete the cache folder and it didn't change.
How can I fix this ?
Thank you
I don't know why symfony tell me that I'm using
Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage
while it's clearing writtenSymfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage
It's not symfony
but PHP
's type checking feature. You are stating that your Listener wants a TokenStorage
but symfony
is passing to it different class, thus the error.
So, as @JaredFarrish pointed, you should be using TokenStorageInterface
in your constructor, like this:
namespace App\EventListener;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
//..
class KernelRequestListener
{
private $tokenStorage;
/**
* KernelRequestListener constructor.
* @param TokenStorageInterface $tokenStorage
* ...
*/
public function __construct(TokenStorageInterface $tokenStorage/*...*/)
{
$this->tokenStorage = $tokenStorage;
//..
}
}
It's a common practice to use interfaces where they exists, because this way you will loose coupling with other classes and provide a way to unit test your classes.
Take a look: https://github.com/symfony/security-bundle/blob/master/Resources/config/security.xml#L22 they switched class for @security.token_storage
service, because of deprecation. But when you use an interface you don't care of anything underlying, you just know that you will have your methods because of interface contract.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With