Php Symfony如何返回所有已登录的活动用户

Php Symfony如何返回所有已登录的活动用户,php,symfony,doctrine,symfony-2.3,Php,Symfony,Doctrine,Symfony 2.3,我想返回我的应用程序的所有登录用户,并将其呈现在我的仪表板中。应从会话中检索user\u id和user\u name(我正在使用外部LDAP库进行身份验证) 我在数据库中创建了一个名为lastActivity的字段,该字段将包含上次登录时间,然后我可以在数据库中查询lastActivity显示最近2分钟内登录的用户 ActivityListener.php <?php namespace Bnpp\SecurityBundle\EventListener; use Doct

我想返回我的应用程序的所有登录用户,并将其呈现在我的仪表板中。应从会话中检索
user\u id
user\u name
(我正在使用外部LDAP库进行身份验证)

我在数据库中创建了一个名为
lastActivity
的字段,该字段将包含上次登录时间,然后我可以在数据库中查询
lastActivity
显示最近2分钟内登录的用户

ActivityListener.php

     <?php

namespace Bnpp\SecurityBundle\EventListener;

use Doctrine\ORM\EntityManager;
//use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Acme\SecurityBundle\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Registry;


/**
 * Listener that updates the last activity of the authenticated user
 */

class ActivityListener

    {
    protected $securityContext;
    protected $entityManager;

    public function __construct(SecurityContext $securityContext, EntityManager $entityManager)
    {
        $this->securityContext = $securityContext;
        $this->entityManager = $entityManager;
    }



    /**
     * Update the user "lastActivity" on each request
     * @param FilterControllerEvent $event
     */


    public function onCoreController(FilterControllerEvent $event)
    {

        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();


            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivity(new \DateTime('now'));
                $this->entityManager->flush($user);
            }
        }

    }

}
用户实体

<?php

namespace Acme\SecurityBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * User
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="Acme\SecurityBundle\Entity\UserRepository")
 */
class User implements UserInterface
{

/**
     * @var \DateTime
     * @ORM\Column(name="LASTACTIVITY", type="datetime")
     */
    private $lastActivity;


    /**
     * @return bool whether the user is active or not
     */

    public function isActiveNow()
     {

    $delay = new\DateTime('2 minutes ago');

    return($this->getlastActivity()>$delay);

       }

/**
     * Set lastActivity
     *
     * @param\Datetime $lastActivity
     * @return User
     */


    public function setlastActivity($lastActivity)
    {
        $this->lastActivity = $lastActivity;

        return $this;
    }


    /**
     * Get lastActivity
     *
     * @return \DateTime
     */
    public function getlastActivity()
    {
        return $this->lastActivity;
    }




}

这里有一篇很棒的帖子:

您可以创建一个侦听器,用于侦听
kernel.controller
事件,并在每次用户处于活动状态时更新用户字段lastActivity。您可以检查
lastActivity
并更新lastActivity时间戳

此外:

下面是如何做到这一点 注意:如果您没有使用FOSUserBundle,请参见下面的编辑

1将其添加到您的用户实体中

/**
 * Date/Time of the last activity
 *
 * @var \Datetime
 * @ORM\Column(name="last_activity_at", type="datetime")
 */
protected $lastActivityAt;

/**
 * @param \Datetime $lastActivityAt
 */
public function setLastActivityAt($lastActivityAt)
{
    $this->lastActivityAt = $lastActivityAt;
}

/**
 * @return \Datetime
 */
public function getLastActivityAt()
{
    return $this->lastActivityAt;
}

/**
 * @return Bool Whether the user is active or not
 */
public function isActiveNow()
{
    // Delay during wich the user will be considered as still active
    $delay = new \DateTime('2 minutes ago');

    return ( $this->getLastActivityAt() > $delay );
}
Same as Step 1 Above
2创建事件侦听器

<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Model\UserInterface;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $userManager;

    public function __construct(SecurityContext $securityContext, UserManagerInterface $userManager)
    {
        $this->securityContext = $securityContext;
        $this->userManager = $userManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof UserInterface) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->userManager->updateUser($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $entityManager;

    public function __construct(SecurityContext $securityContext, EntityManager $entityManager)
    {
        $this->securityContext = $securityContext;
        $this->entityManager = $entityManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->entityManager->flush($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $tokenContext;
    protected $doctrine;

    public function __construct(TokenyContext $tokenContext, $doctrine)
    {
        $this->tokenContext= $tokenContext;
        $this->doctrine= $doctrine;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->tokenContext->getToken()) {
            $user = $this->tokenContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->doctrine->getManager()->flush($user);
            }
        }
    }
}
你可以走了

编辑(不带FOSUserBundle) 1将其添加到您的用户实体中

/**
 * Date/Time of the last activity
 *
 * @var \Datetime
 * @ORM\Column(name="last_activity_at", type="datetime")
 */
protected $lastActivityAt;

/**
 * @param \Datetime $lastActivityAt
 */
public function setLastActivityAt($lastActivityAt)
{
    $this->lastActivityAt = $lastActivityAt;
}

/**
 * @return \Datetime
 */
public function getLastActivityAt()
{
    return $this->lastActivityAt;
}

/**
 * @return Bool Whether the user is active or not
 */
public function isActiveNow()
{
    // Delay during wich the user will be considered as still active
    $delay = new \DateTime('2 minutes ago');

    return ( $this->getLastActivityAt() > $delay );
}
Same as Step 1 Above
2创建事件侦听器

<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Model\UserInterface;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $userManager;

    public function __construct(SecurityContext $securityContext, UserManagerInterface $userManager)
    {
        $this->securityContext = $securityContext;
        $this->userManager = $userManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof UserInterface) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->userManager->updateUser($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $entityManager;

    public function __construct(SecurityContext $securityContext, EntityManager $entityManager)
    {
        $this->securityContext = $securityContext;
        $this->entityManager = $entityManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->entityManager->flush($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $tokenContext;
    protected $doctrine;

    public function __construct(TokenyContext $tokenContext, $doctrine)
    {
        $this->tokenContext= $tokenContext;
        $this->doctrine= $doctrine;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->tokenContext->getToken()) {
            $user = $this->tokenContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->doctrine->getManager()->flush($user);
            }
        }
    }
}

你可以走了由于我无法对帖子发表评论,我仍然想通过这个答案对答案发表评论

由于Symfony 2.6不推荐使用SecurityContext类,在本例中,应改用TokenStorage类

因此,services.yml将如下所示:

services:
    acme_user.activity_listener:
        class: %acme_user.activity_listener.class%
        arguments: ['@security.token_storage', '@doctrine.orm.entity_manager']
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
而不是

use Symfony\Component\Security\Core\SecurityContext;
应该

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
(还将类内的SecurityContext替换为TokenStorage类)

然后,在第38行,将使用

$this->tokenStorage->getToken()
并且,在第39行,用户实例将使用

$this->tokenStorage->getToken()->getUser()

Symfony 3.4的更新

1。将其添加到您的用户实体中

/**
 * Date/Time of the last activity
 *
 * @var \Datetime
 * @ORM\Column(name="last_activity_at", type="datetime")
 */
protected $lastActivityAt;

/**
 * @param \Datetime $lastActivityAt
 */
public function setLastActivityAt($lastActivityAt)
{
    $this->lastActivityAt = $lastActivityAt;
}

/**
 * @return \Datetime
 */
public function getLastActivityAt()
{
    return $this->lastActivityAt;
}

/**
 * @return Bool Whether the user is active or not
 */
public function isActiveNow()
{
    // Delay during wich the user will be considered as still active
    $delay = new \DateTime('2 minutes ago');

    return ( $this->getLastActivityAt() > $delay );
}
Same as Step 1 Above
与上述步骤1相同

2。创建事件侦听器

<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Model\UserInterface;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $userManager;

    public function __construct(SecurityContext $securityContext, UserManagerInterface $userManager)
    {
        $this->securityContext = $securityContext;
        $this->userManager = $userManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof UserInterface) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->userManager->updateUser($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $securityContext;
    protected $entityManager;

    public function __construct(SecurityContext $securityContext, EntityManager $entityManager)
    {
        $this->securityContext = $securityContext;
        $this->entityManager = $entityManager;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->entityManager->flush($user);
            }
        }
    }
}
<?php
namespace Acme\UserBundle\EventListener;

use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Doctrine\ORM\EntityManager;
use Acme\UserBundle\Entity\User;

/**
 * Listener that updates the last activity of the authenticated user
 */
class ActivityListener
{
    protected $tokenContext;
    protected $doctrine;

    public function __construct(TokenyContext $tokenContext, $doctrine)
    {
        $this->tokenContext= $tokenContext;
        $this->doctrine= $doctrine;
    }

    /**
    * Update the user "lastActivity" on each request
    * @param FilterControllerEvent $event
    */
    public function onCoreController(FilterControllerEvent $event)
    {
        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->tokenContext->getToken()) {
            $user = $this->tokenContext->getToken()->getUser();

            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivityAt(new \DateTime());
                $this->doctrine->getManager()->flush($user);
            }
        }
    }
}
对于Symfony3.4(4),我使用EntityManagerInterface来更新用户,并使用安全性来获取用户,以下代码适用于我:

app/config/services.yml

AppBundle\Service\ActivityListener:
标签:
-{name:'kernel.event_listener',event:'kernel.controller',method:OnReconController}
Service/ActivityListener.php

     <?php

namespace Bnpp\SecurityBundle\EventListener;

use Doctrine\ORM\EntityManager;
//use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Acme\SecurityBundle\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Registry;


/**
 * Listener that updates the last activity of the authenticated user
 */

class ActivityListener

    {
    protected $securityContext;
    protected $entityManager;

    public function __construct(SecurityContext $securityContext, EntityManager $entityManager)
    {
        $this->securityContext = $securityContext;
        $this->entityManager = $entityManager;
    }



    /**
     * Update the user "lastActivity" on each request
     * @param FilterControllerEvent $event
     */


    public function onCoreController(FilterControllerEvent $event)
    {

        // Check that the current request is a "MASTER_REQUEST"
        // Ignore any sub-request
        if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) {
            return;
        }

        // Check token authentication availability
        if ($this->securityContext->getToken()) {
            $user = $this->securityContext->getToken()->getUser();


            if ( ($user instanceof User) && !($user->isActiveNow()) ) {
                $user->setLastActivity(new \DateTime('now'));
                $this->entityManager->flush($user);
            }
        }

    }

}

Symfony 4中,我用以下方法解决了问题

<?php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;

class ActivitySubscriber implements EventSubscriberInterface {

    private $em;
    private $security;

    public function __construct(
    EntityManagerInterface $em, Security $security) {
        $this->em = $em;
        $this->security = $security;
    }

    public function onTerminate() {
        $user = $this->security->getUser();

        if (!$user->isActiveNow()) {
            $user->setLastActivityAt(new \DateTime());
            $this->em->persist($user);
            $this->em->flush($user);
        }
    }

    public static function getSubscribedEvents() {
        return [
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::TERMINATE => [['onTerminate', 20]],
        ];
    }

}

这里有问题吗?会话对所有用户来说都不是全局的;在这种情况下,您应该查询数据库并选择所有登录时间>=now()的用户-5分钟如果您在数据库中保存会话数据,您可以从数据库中获取活动会话列表,并假设这些用户已登录。@Petar Zivkovic-我创建了一个表,其中记录了用户id和上次登录时间。如何查询数据库以显示登录时间>=now()-5分钟?你能用示例代码来说明吗?ThanksI我还在为如何创建事件侦听器而挣扎?您能给我一个示例代码吗?我如何侦听kernel.controller事件并更新lastActivity?我应该创建服务吗?谢谢@Patt我已经用代码更新了我的问题。请看一看我的更新,我测试了自己,它的工作。希望有帮助!谢谢你的更新。有没有一种不使用FOS用户包的方法来实现它?我在侦听器服务中尝试了实体管理器注入。我将@doctor.orm.entity_manager作为参数传递,但它给出了如下错误-可捕获的致命错误:传递给Acme\SecurityBundle\EventListener\ActivityListener的参数2::u construct()必须是doctor\orm\entitymanagersity Symfony2.4的实例,如果($event->isMasterRequest()){…},您也可以使用
if($event->isMasterRequest())
检查当前请求是否为
主\u请求
。我知道这是一篇老文章,但我想纠正一下你的打字错误。在参数中的services.yml中,应该使用security.token_存储,而不是security.context.+1来使用事件订阅服务器。您在说
$this->em->flush($user)时出错应该是
$this->em->persist($user)$这->em->flush()@DanMeigs谢谢。我在代码中检测到了它,但我没有在帖子中修改它。