简体   繁体   English

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

[英]Symfony + JMS Serializer: How to set default Timezone?

I am working on a Symfony webapp project and have a problem with the timezone used by the JMS Serializer. 我正在开发一个Symfony webapp项目,并且JMS序列化器使用的时区有问题。

Short version: 简洁版本:

How can I set a global default timezone that is used all over my symfony project, not matter if the project is used in the browser or on the command line? 如何设置在我的symfony项目中使用的全局默认时区,而不管该项目是在浏览器中还是在命令行中使用?

(very) Long Version: (非常)长版:

  • In the global sever php.ini timezone is set as date.timezone = "America/Chicago" 在全局服务器php.ini中,时区设置为date.timezone = "America/Chicago"
  • The webapp however should use UTC as default timezone. 但是,Web应用程序应使用UTC作为默认时区。

To achieve this I simply added ini_set("date.timezone", "UTC"); 为此,我只添加了ini_set("date.timezone", "UTC"); to the app.php and app_dev.php FrontControllers. app.phpapp_dev.php FrontControllers。 Since every access to the app is routed through these files, this solutions works quite well. 由于对应用程序的每次访问都通过这些文件进行路由,因此该解决方案效果很好。

However there is one big problem with this solution: It only works when the app is being used through these FrontControllers / in the browser. 但是,此解决方案存在一个大问题:仅当通过这些FrontControllers /在浏览器中使用该应用程序时,它才有效。

When ever I use the console or any other commandline access to the project the Frontcontrollers are not uses and thus the timezone setting is not applied. 每当我使用控制台或任何其他命令行访问项目时,都不会使用Frontcontrollers,因此不会应用时区设置。

This is a problem for example when clearing and warming up the cache: 例如,在清除和预热缓存时,这是一个问题:

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

Since php is used directly on the commandline the global php.ini is used. 由于php直接在命令行上使用,因此使用全局php.ini Thus the global date.timezone = "America/Chicago" is applied. 因此,将应用全局date.timezone = "America/Chicago"

It seems that the default timezone is stored in appDevDebugProjectContainer.xml cache file and additionally the timezone is cached for the JMS Serializer as well in: 似乎默认时区存储在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);

Thus every time an object is (de)serialized using JMS the wrong timezone is applied to all dates. 因此,每次使用JMS对对象进行序列化时,都会将错误的时区应用于所有日期。 This is even the case when the app is running the browser (using the FrontControllers with changed default timezone). 甚至在应用程序运行浏览器(使用具有更改的默认时区的FrontController)时也是如此。

Of course the problem is the same for all other console commands, since they all use the global php.ini. 当然,所有其他控制台命令的问题都相同,因为它们都使用全局php.ini。 How can I solve this? 我该如何解决?

Possible Solutions: 可能的解决方案:

  • Change timezone in global php.ini: Not possible because I have not root access to the server and the same php.ini is shared between different domains/project. 在全局php.ini中更改时区:不可能,因为我没有对服务器的root访问权限,并且同一php.ini在不同的域/项目之间共享。 Other domains/projects need America/Chicago as default time zone 其他域/项目需要America/Chicago作为默认时区
  • Use local php.ini for the project: Not possible because a php.ini only applies to the php files within the same folder. 对项目使用本地php.ini:不可能,因为php.ini仅适用于同一文件夹中的php文件。 Creating and maintaining a php.ini in every project folder is not possible. 不可能在每个项目文件夹中创建和维护php.ini。
  • Use local php.ini for command line php calls : The Frontontrollers would still set the time zone for all "browser" calls to the app. 使用本地php.ini进行命令行php调用 :Frontontrollers仍然会为应用程序的所有“浏览器”调用设置时区。 Additionally I would create one php.ini for the project that is being uses as parameter when using php on the commandline: 另外,我会为在命令行上使用php时用作参数的项目创建一个 php.ini:

Code: 码:

// in ./.bashrc
alias phpx='php -c /path/to/project/php.ini'

// use phpx instead of php
phpx app/console cache:clear --env=dev

This solution would work but I do not like it: 此解决方案可以工作,但我不喜欢它:

  • I have to maintain two php.ini files. 我必须维护两个php.ini文件。 The global php.ini and the project php.ini. 全局php.ini和项目php.ini。 Since the INIs are not combined (take one option from iniA and all other options form iniB) this possible but cumbersome. 由于不将INI组合在一起(从iniA中选择一个选项,从iniB中选择所有其他选项),因此可能会很麻烦。
  • I am still not 100% sure if there are not any internal php calls that might not be routed through the FrontControllers and thus might use the wrong timezone: 我仍然不是100%确定是否没有任何内部php调用可能不会通过FrontControllers路由,因此可能使用错误的时区:

Conclusion: 结论:

Is there any option that will set the default timezone globally for the complete Symfony project? 是否有任何选项可以为整个Symfony项目全局设置默认时区? So far I only found an option that was used in Symfony 1.x but no equivalent solution for Symfony 2.x 到目前为止,我只找到了Symfony 1.x中使用选项,但没有Symfony 2.x的等效解决方案

Any idea? 任何想法?

Well, sometimes an answer is so obvious that one cannot see it. 好吧,有时候答案很明显,以至于看不到它。 At least not before writing a long question here... :-) 至少在这里写一个长问题之前不是... :-)

Right after I send the question I found the answer: The default timezone should be applied globally, all over Symfony, no matter how it is being used (browser, console, etc.)? 在我发送问题之后,我立即找到了答案:无论使用哪种方式(浏览器,控制台等),默认时区都应该在整个Symfony中全局应用。 So, which part of Symfony is beeing use every time and every where? 那么,Symfony的哪一部分在任何时间,任何地方都在使用? The Kernel!! 内核!

I simply modified the AppKernel and it works fine: 我只是修改了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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM