Letzte Woche mussten wir eine datetime
-Spalte in eine Datenbanktabelle einfügen. Das Problem war, dass wir diese datetime
mit Mikrosekunden brauchten, also so etwas wie 2019-10-31 07: 23: 38.774932. Dies wird vom Doctrine DBAL-Paket nicht unterstützt. Im Moment benutzen wir PHP 7.3.9, Symfony 4.3.5, Doctrine/DBAL 2.9.2 und MySQL 5.7.26 in der Entwicklung. So haben wir es gelöst:
namespace App\System\Infrastructure\DbalTypes; use DateTime; use DateTimeInterface; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\DBAL\Types\ConversionException; use Doctrine\DBAL\Types\DateTimeType as DbalDateTimeType; use Doctrine\DBAL\Types\Type; final class DateTimeType extends DbalDateTimeType { public function getName() { return Type::DATETIME; } public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) { if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) { return 'TIMESTAMP'; } if ($platform instanceof PostgreSqlPlatform) { return 'TIMESTAMP(6) WITHOUT TIME ZONE'; } else { return 'DATETIME(6)'; } } public function convertToDatabaseValue($value, AbstractPlatform $platform) { if ($value === null) { return $value; } if ($value instanceof DateTimeInterface) { return $value->format('Y-m-d H:i:s.u'); } throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']); } public function convertToPHPValue($value, AbstractPlatform $platform) { if ($value === null || $value instanceof DateTimeInterface) { return $value; } $val = DateTime::createFromFormat('Y-m-d H:i:s.u', $value); if (!$val) { $val = date_create($value); } if (!$val) { throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); } return $val; } }
Nachdem wir die neuen Konfigurationen haben, müssen wir die in Doctrine integrierten Konfigurationen irgendwie überschreiben. Zu diesem Zweck haben wir der Datei bootstrap.php
im Ordner config
Folgendes hinzugefügt:
use Doctrine\DBAL\Types\Type; use App\System\Infrastructure\DbalTypes\DateTimeType; ... Type::overrideType(Type::DATETIME, DateTimeType::class);