Поле даты и времени Symfony 4 Entity возвращает текущую дату вместо базы данных

Поле даты и времени Symfony 4 Entity возвращает текущую дату вместо базы данных.

У меня есть образ Entity, в котором дата обновления хранится в поле с именем updatedAt.

    <?php /** @noinspection PhpFullyQualifiedNameUsageInspection */

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity(repositoryClass = "App\Repository\ImageRepository")
 * @Vich\Uploadable
 */
class Image
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @var File
     * @Vich\UploadableField(mapping = "images", fileNameProperty = "name")
     */
    private $file;

    /**
     * @var string
     * @ORM\Column(type = "string", length=255)"
     */
    private $name;

    /**
     * @var \DateTime
     * @ORM\Column(type = "datetime")
     */
    private $updatedAt;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\Tag", inversedBy = "images", cascade = {"persist"})
     */
    private $tags;

    public function __construct()
    {
        $this->updatedAt = new \DateTime();
        $this->tags = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getFile(): ?File
    {
        return $this->file;
    }

    public function setFile(?File $file = null): void
    {
        $this->file = $file;
        if ($file !== null) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTime();
        }
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getUpdatedAt(): ?\DateTimeInterface
    {
        return $this->updatedAt;
    }

    public function setUpdatedAt(\DateTimeInterface $updatedAt): self
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }


}

Но когда я получаю его из базы данных, поле updatedAt показывает текущее время данных, как показано ниже:

Image {#646 ▼
  -id: 27
  -file: File {#698 ▶}
  -name: "kPRHHeCVrT.jpg"
  -updatedAt: DateTime @1558609804 {#706 ▼
    date: 2019-05-23 11:10:04.486082 UTC (+00:00)
  }
  -tags: PersistentCollection {#686 ▶}
}

и var_dump($this->updatedAt) в методе getUpdatedAt показывает это:

object(DateTime)#626 (3) { ["date"]=> string(26) "2019-05-19 21:17:48.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 

object(DateTime)#680 (3) { ["date"]=> string(26) "2019-05-23 11:24:12.746548" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 

обратите внимание на 2 разных объекта. Я не понимаю, почему это так.

Можете ли вы показать, как вы устанавливаете дату? Потому что кажется, что вы сохраняете значение по умолчанию для своей даты

Dylan Kas 23.05.2019 14:00

код для сеттера выше.

Salim Ben Aissa 23.05.2019 15:15

И все, что вы делаете, это просто $imageRepo->find($id) сразу после чего следует dump($image) ? Конечно, похоже, что вы где-то обновляете изображение или, возможно, у вас есть какой-то пользовательский прослушиватель событий доктрины. (Не по теме, но Функция дампа Symfony обычно лучше, чем встроенная функция php var_dump).

Cerad 23.05.2019 15:22

Да, я пробовал встроенную функцию дампа, и она печатает тот же результат. но в любом случае я извлекаю объект с помощью ParameterConverter, также с функцией findAll. Я использую VichUploader с параметрами CurrentDateTimeDirectoryNamer: directory_namer: service: Vich\UploaderBundle\Naming\CurrentDateTimeDirectoryNamer options: date_time_format: 'Y/d/m' date_time_property: uploadTimestamp

Salim Ben Aissa 23.05.2019 15:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
4
2 362
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как говорится в комментариях в вашем коде (поскольку вы сохранили его от официального VichUploaderBundle документация):

public function setFile(?File $file = null): void
{
    $this->file = $file;
    if ($file !== null) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new \DateTime();
    }
}

Таким образом, это означает, что каждый раз, когда вы вызываете свой метод установить файл (), вы назначаете текущую дату своему свойству $this->updatedAt. Метод вызывается каждый раз, когда вы создаете/обновляете объект изображения, поэтому он всегда будет содержать текущую дату. Это также могло произойти из-за того, что для параметра inject_on_load установлено значение true в yaml-файле конфигурации vich.

Я предлагаю вам добавить новое свойство с именем vichUpdatedAt() и использовать его вместо updatedAt() :

  • vichUpdatedAt будет использоваться пакетом.
  • updateAt будет использоваться всем остальным.

БОНУС: Я рекомендую вам установить эти расширения: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html Это позволит вам легко добавлять свойства udpatedAt и createdAt в любом месте.

Активируйте желаемое расширение (в /config/packages/stof_doctrine_extensions.yaml), так что для нас прямо сейчас это будет расширение с отметкой времени:

stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            timestampable: true

Затем в вашем классе изображений просто добавьте:

use Gedmo\Timestampable\Traits\TimestampableEntity;
class Image {
   use TimestampableEntity;
   ....
}

И вот, бесплатные свойства updatedAt и createdAt, больше ничего не нужно делать, это просто работает.

Я использовал ту же логику в другом проекте, и я просто сделал то же самое, что и раньше. Это должно быть что-то, чего нам не хватает, также обратите внимание на новый DateTime() в конструкторе, который я делал из dacates.

Salim Ben Aissa 23.05.2019 15:38

Забыл сказать вам, что основная проблема заключается в том, что пакет не может отображать актив, поскольку он сохраняется с использованием currentDateDirectoryNamer, который, конечно, будет использовать текущую дату, а не updatedAt, и поэтому я не получаю актив

Salim Ben Aissa 23.05.2019 15:42

@SalimBenAissa Вы используете inject_on_load: true ? (в vich_uploader.yaml)

Elbarto 23.05.2019 15:52

Ind yes и изменение его на false решило проблему. Но я больше не могу получить доступ к файлу из объекта, я думаю, что лучший вариант - я следую вашему демарху или просто удаляю обновление в setFile, так как обычно я не буду изменять файл, а скорее удалю его и загружу другой.

Salim Ben Aissa 23.05.2019 16:01

вместо этого вы можете загрузить свое изображение вручную в службу, вызываемую вашим контроллером, если у вас для inject_on_load установлено значение false, но да, это еще больше работы!

Elbarto 23.05.2019 16:04

@SalimBenAissa обычно возникает вопрос, если включена функция inject_on_load, setFile() следует вызывать при обновлении или создавать не в методе получения. Итак, вопрос, почему setFile называется?

famas23 25.10.2020 23:47

Другие вопросы по теме