Symfony2:在何处设置用户定义的时区

时间:2012-05-22 00:24:44

标签: php symfony timezone

我对当前项目的要求之一是允许用户为其帐户选择时区,然后将此时区用于整个站点中的所有日期/时间相关功能。

我看到它的方式,我有两个选择:

  • 将DateTimeZone对象传递给DateTime的每个新DateTime的构造函数
  • 使用PHP的date_default_timezone_set()
  • 设置默认时区

似乎使用date_default_timezone_set是可行的方法,但我不确定应该在哪里设置它。由于时区将因用户而异,并且在整个站点上使用了DateTime,我需要将其设置为会影响所有页面的位置。

也许我可以写一个成功登录后设置它的事件监听器?如果我采用这种方法,它是否会在所有页面上保持设置,还是仅按页面设置?

我很想听听其他人如何接近这一点。

1 个答案:

答案 0 :(得分:14)

是的,您可以使用事件监听器,挂钩kernel.request事件。

以下是我的一个项目的听众:

<?php
namespace Vendor\Bundle\AppBundle\Listener;

use Symfony\Component\Security\Core\SecurityContextInterface;
use Doctrine\DBAL\Connection;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Observe;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Inject;

/**
 * @Service
 */
class TimezoneListener
{
    /**
     * @var \Symfony\Component\Security\Core\SecurityContextInterface
     */
    private $securityContext;

    /**
     * @var \Doctrine\DBAL\Connection
     */
    private $connection;

    /**
     * @InjectParams({
     *     "securityContext" = @Inject("security.context"),
     *     "connection"      = @Inject("database_connection")
     * })
     *
     * @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext
     * @param \Doctrine\DBAL\Connection $connection
     */
    public function __construct(SecurityContextInterface $securityContext, Connection $connection)
    {
        $this->securityContext = $securityContext;
        $this->connection      = $connection;
    }

    /**
     * @Observe("kernel.request")
     */
    public function onKernelRequest()
    {
        if (!$this->securityContext->isGranted('ROLE_USER')) {
            return;
        }

        $user = $this->securityContext->getToken()->getUser();
        if (!$user->getTimezone()) {
            return;
        }

        date_default_timezone_set($user->getTimezone());
        $this->connection->query("SET timezone TO '{$user->getTimezone()}'");
    }
}