我对当前项目的要求之一是允许用户为其帐户选择一个时区,然后将此时区用于整个站点中与日期/时间相关的所有功能。
在我看来,我有两个选择:
- 将 DateTimeZone 对象传递给每个新 DateTime 的 DateTime 构造函数
- 使用 PHP 的
date_default_timezone_set()
设置默认时区
似乎使用 date_default_timezone_set 是要走的路,但我不确定我应该在哪里设置它。 由于时区因用户而异,并且整个站点都使用日期时间,因此我需要将其设置在会影响所有页面的位置。
也许我可以编写一个事件侦听器,在成功登录后设置它? 如果我采用这种方法,它是在所有页面上保持设置还是仅按页面设置?
我很想听听其他人会如何处理这个问题。
是的,您可以使用事件侦听器,挂接kernel.request
事件。
这是我的一个项目的听众:
<?php
namespace VendorBundleAppBundleListener;
use SymfonyComponentSecurityCoreSecurityContextInterface;
use DoctrineDBALConnection;
use JMSDiExtraBundleAnnotationService;
use JMSDiExtraBundleAnnotationObserve;
use JMSDiExtraBundleAnnotationInjectParams;
use JMSDiExtraBundleAnnotationInject;
/**
* @Service
*/
class TimezoneListener
{
/**
* @var SymfonyComponentSecurityCoreSecurityContextInterface
*/
private $securityContext;
/**
* @var DoctrineDBALConnection
*/
private $connection;
/**
* @InjectParams({
* "securityContext" = @Inject("security.context"),
* "connection" = @Inject("database_connection")
* })
*
* @param SymfonyComponentSecurityCoreSecurityContextInterface $securityContext
* @param DoctrineDBALConnection $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()}'");
}
}