Symfony Doctrine - 设置时区

问题描述 投票:0回答:3

我在同一台服务器上运行多个 Symfony 应用程序,每个应用程序可能需要不同的时区。

对于 php,可以通过使用不同的 fpm 池并在池配置中设置时区来实现:

php_admin_value[date.timezone] = America/New_York

但是对于MySQL,我需要发出以下语句:

"SET time_zone = 'America/New_York';

作为连接后的第一个查询,或添加到 PDO 构造函数中的 $options 数组中:

PDO::MYSQL_ATTR_INIT_COMMAND => "SET time_zone = 'America/New_York';"

这怎么办?

symfony doctrine
3个回答
5
投票

您可以使用 PostConnect Doctrine 事件... https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/events.html#postconnect-event

这对于在执行任何 sql 语句之前配置连接很有用。

一个例子可能是:

<?php

namespace App\EventListener;

use Doctrine\DBAL\Event\ConnectionEventArgs;

/**
 * My initializer
 */
class  MyPdoInitializerListener
{
    public function postConnect(ConnectionEventArgs $args)
    {
        $args->getConnection()
            ->exec("SET time_zone = 'America/New_York'");
    }
}

不要忘记将监听器添加到 services.yaml

# services.yaml

    # ...

    App\EventListener\MyPdoInitializerListener:
        tags:
            - { name: doctrine.event_listener, event: postConnect }

2
投票

为了扩展 SilvioQ 的答案,我编写了以下代码片段以从 PHP 环境继承时区,假设之前调用了

date_default_timezone_set()
来设置正确的时区:

当命名时区

在 MySQL/MariaDB 中不可用并且您无法控制服务器时,此解决方案比命名时区(如 
"America/New_York")具有优势。

public function postConnect(ConnectionEventArgs $args) { $tz = new DateTimeZone(date_default_timezone_get()); $offset = $tz->getOffset(new DateTime('now')); $abs = abs($offset); $str = sprintf('%s%02d:%02d', $offset < 0 ? '-' : '+', intdiv($abs, 3600), intdiv($abs % 3600, 60)); $args->getConnection()->exec("SET time_zone = '$str'"); }
    

0
投票
从 Doctrine DBAL 3.5 版本开始,SilvioQ 提出的解决方案已被弃用。

Doctrine 文档建议为数据库驱动程序实现一个中间件类。此类实现的示例可以在 DBAL 代码本身中找到:

src/Logging/Middleware.php

© www.soinside.com 2019 - 2024. All rights reserved.