Symfony+JMS序列化程序:如何设置默认时区


Symfony + JMS Serializer: How to set default Timezone?

我正在处理一个Symfony Web应用程序项目,JMS序列化程序使用的时区有问题。

短版本:

我如何设置一个全局默认时区,该时区在我的symfony项目中使用,无论该项目是在浏览器中还是在命令行中使用?

(非常)长版本:

  • 在全局服务器php.ini中,时区设置为date.timezone = "America/Chicago"
  • 但是,Web应用程序应该使用UTC作为默认时区

为了实现这一点,我简单地将ini_set("date.timezone", "UTC");添加到app.phpapp_dev.php FrontControllers中。由于对应用程序的每次访问都是通过这些文件进行路由的,因此此解决方案运行良好。

然而,这个解决方案有一个大问题:只有当应用程序通过浏览器中的这些FrontControllers/使用时,它才有效。

当我使用控制台或任何其他命令行访问项目时,都不会使用Frontcontrollers,因此不会应用时区设置。

这是一个问题,例如在清除和预热缓存时:

php app/console cache:clear --env=dev

由于php直接在命令行上使用,因此使用全局php.ini。从而应用全局CCD_ 8。

默认时区似乎存储在appDevDebugProjectContainer.xml缓存文件中,此外,JMS序列化程序的时区也缓存在:中

$ cd ...../app/cache/dev
$ grep -rnw .'/' -e "America/Chicago"
./appDevDebugProjectContainer.xml:4125:      <argument>America/Chicago</argument>
./appDevDebugProjectContainer.php:3083:        return $this->services['jms_serializer.datetime_handler'] = new 'JMS'Serializer'Handler'DateHandler('Y-m-d''TH:i:sO', 'America/Chicago', true);

因此,每次使用JMS序列化对象时,都会将错误的时区应用于所有日期。即使在应用程序运行浏览器时也是如此(使用更改了默认时区的FrontControllers)。

当然,所有其他控制台命令的问题都是一样的,因为它们都使用全局php.ini。我该如何解决这个问题

可能的解决方案:

  • 更改全局php.ini中的时区:不可能,因为我没有对服务器的root访问权限,并且不同域/项目之间共享相同的php.ini。其他域/项目需要America/Chicago作为默认时区
  • 对项目使用本地php.ini:不可能,因为php.ini只适用于同一文件夹中的php文件。不可能在每个项目文件夹中创建和维护php.ini
  • 使用本地php.ini进行命令行php调用:Frontontrollers仍然会为应用程序的所有"浏览器"调用设置时区。此外,当在命令行上使用php时,我会为正在用作参数的项目创建一个php.ini:

代码:

// in ./.bashrc
alias phpx='php -c /path/to/project/php.ini'
// use phpx instead of php
phpx app/console cache:clear --env=dev

这个解决方案会起作用,但我不喜欢它:

  • 我必须维护两个php.ini文件。全局php.ini和项目php.ini。由于ini没有组合(从iniA中选择一个选项,从iniB中选择所有其他选项),这可能但很麻烦
  • 我仍然不能100%确定是否没有任何内部php调用可能无法通过FrontControllers路由,从而可能使用错误的时区:

结论:

有没有任何选项可以为整个Symfony项目全局设置默认时区?到目前为止,我只找到了Symfony 1.x中使用的选项,但没有Symfony 2.x 的等效解决方案

知道吗?

好吧,有时答案太明显了,以至于看不见。至少在这里写一个长问题之前…:-)

在我发送问题后,我找到了答案:默认时区应该在全局范围内应用,在Symfony上,无论它是如何使用的(浏览器、控制台等)?那么,Symfony的哪一部分在任何时候、任何地方都在使用呢内核

我只是简单地修改了AppKernel,它运行良好:

class AppKernel extends Kernel
{   
    public function __construct($environment, $debug)
    {
        // Two is better than one...
        ini_set("date.timezone", "UTC");
        date_default_timezone_set('UTC');
        parent::__construct($environment, $debug);
    }
}