如何在Symfony框架中拥有可选服务


How can I have optional services in the Symfony framework?

我希望能够从容器中获取当前登录用户的凭据(电子邮件,密码等)。所以,这就是我所做的:

security.token:
    class: Symfony'Component'Security'Core'Authentication'Token'TokenInterface
    factory: ["@security.token_storage", "getToken"]
    private: true
security.current_user_credentials:
    class: Symfony'Component'Security'Core'User'UserInterface 
    factory: ["@security.token", "getUser"]
security.current_user:
    class: AppBundle'Entity'User
    factory: ["@security.current_user_credentials", "getUser"]

当我这样做并且我登录时,它工作正常。但是,当我注销时,我得到dev.log

[2015-06-22 12:28:11] php.CRITICAL: Fatal Error: Call to a member function getUser() on string {"type":1,"file":"/var/www/html/phoenix/app/cache/dev/appDevDebugProjectContainer.php","line":3107,"level":-1,"stack":[{"function":"getSecurity_CurrentUserService","type":"->","class":"appDevDebugProjectContainer","file":"/var/www/html/phoenix/app/bootstrap.php.cache","line":2140,"args":[]},{"function":"get","type":"->","class":"Symfony''Component''DependencyInjection''Container","file":"/var/www/html/phoenix/app/cache/dev/appDevDebugProjectContainer.php","line":674,"args":[]},{"function":"getCommandHistoryCreatorService","type":"->","class":"appDevDebugProjectContainer","file":"/var/www/html/phoenix/app/bootstrap.php.cache","line":2140,"args":[]},{"function":"get","type":"->","class":"Symfony''Component''DependencyInjection''Container","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1929,"args":[]},{"function":"lazyLoad","type":"->","class":"Symfony''Component''EventDispatcher''ContainerAwareEventDispatcher","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1894,"args":[]},{"function":"getListeners","type":"->","class":"Symfony''Component''EventDispatcher''ContainerAwareEventDispatcher","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php","line":99,"args":[]},{"function":"getListeners","type":"->","class":"Symfony''Component''EventDispatcher''Debug''TraceableEventDispatcher","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php","line":158,"args":[]},{"function":"getNotCalledListeners","type":"->","class":"Symfony''Component''EventDispatcher''Debug''TraceableEventDispatcher","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php","line":48,"args":[]},{"function":"lateCollect","type":"->","class":"Symfony''Component''HttpKernel''DataCollector''EventDataCollector","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Profiler/Profiler.php","line":115,"args":[]},{"function":"saveProfile","type":"->","class":"Symfony''Component''HttpKernel''Profiler''Profiler","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php","line":146,"args":[]},{"function":"onKernelTerminate","type":"->","class":"Symfony''Component''HttpKernel''EventListener''ProfilerListener","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php","line":61,"args":[]},{"function":"call_user_func:{/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php:61}","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php","line":61,"args":[]},{"function":"__invoke","type":"->","class":"Symfony''Component''EventDispatcher''Debug''WrappedListener","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1824,"args":[]},{"function":"call_user_func:{/var/www/html/phoenix/app/cache/dev/classes.php:1824}","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1824,"args":[]},{"function":"doDispatch","type":"->","class":"Symfony''Component''EventDispatcher''EventDispatcher","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1757,"args":[]},{"function":"dispatch","type":"->","class":"Symfony''Component''EventDispatcher''EventDispatcher","file":"/var/www/html/phoenix/app/cache/dev/classes.php","line":1918,"args":[]},{"function":"dispatch","type":"->","class":"Symfony''Component''EventDispatcher''ContainerAwareEventDispatcher","file":"/var/www/html/phoenix/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php","line":124,"args":[]},{"function":"dispatch","type":"->","class":"Symfony''Component''EventDispatcher''Debug''TraceableEventDispatcher","file":"/var/www/html/phoenix/app/bootstrap.php.cache","line":3067,"args":[]},{"function":"terminate","type":"->","class":"Symfony''Component''HttpKernel''HttpKernel","file":"/var/www/html/phoenix/app/bootstrap.php.cache","line":2409,"args":[]},{"function":"terminate","type":"->","class":"Symfony''Component''HttpKernel''Kernel","file":"/var/www/html/phoenix/web/app_dev.php","line":20,"args":[]},{"function":"{main}","file":"/var/www/html/phoenix/web/app_dev.php","line":0,"args":[]}]} []

是否可以使security.current_user_credentialssecurity.current_user可选?此错误是由这些服务引起的吗?

最近我遇到了类似的问题,如果您尝试访问不存在的路由,您可能会看到相同的错误。我正在处理一项任务,我需要在我的服务中掌握登录用户,这就是我实现它的方式

我的services.yml

services:
    student_application_subscriber:
        class: namespace'YourBundle'EventListener'StudentApplicationSubscriber
        arguments:
            - @doctrine.orm.entity_manager
            - @security.token_storage
            - @security.authorization_checker
            - @twig

这是我的服务类StudentApplicationSubscriber

namespace yournamespace'YourBundleBundle'EventListener;
use Doctrine'ORM'EntityManager;
use Symfony'Component'EventDispatcher'EventSubscriberInterface;

class StudentApplicationSubscriber implements EventSubscriberInterface
{
    protected $em;
    protected $twig;
    protected $tokenStorage;
    protected $authChecker;
    function __construct(EntityManager $em, $tokenStorage, $authChecker, $twig)
    {
        $this->em = $em;
        $this->twig = $twig;
        $this->tokenStorage = $tokenStorage;
        $this->authChecker = $authChecker;
    }
    public static function getSubscribedEvents()
    {
        return array(
            'kernel.request' => 'onKernelRequest'
        );
    }
    public function onKernelRequest()
    {
        if (!$token = $this->tokenStorage->getToken()) {
            return;
        }
        $user = $token->getUser();
        if (!is_object($user)) {
            // there is no user - the user may not be logged in
            return;
        }
        //get details of logged in user
        $get_user_details = $this->tokenStorage->getToken()->getUser();
        //make sure to pull information when user is logged in
        if ($this->authChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
            //get user id of logged in user
            $userId = $get_user_details->getId();
        //perform your logic here
        }

    }
}

你想实现什么?乍一看,我建议要么有一个内核侦听器来检查是否有用户并执行所需的操作,要么在您的security.current_user_credentials中检查它。

我想,如果您只是传递给您的服务并在该函数中添加以下逻辑,那么它适用于匿名用户和经过身份验证的用户:

function dummyFunction($securityContext)) {
$email = $username = '';
if($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
   $email = $securityContext->getToken()->getUser()->getEmail();
   $username = $securityContext->getToken()->getUser()->getUsername();
}
 ..........................
}