cakephp 3.8.8 Невозможно преобразовать значение типа `string` в целое число при сохранении крайнего срока поля как datetime

Cakephp не сохраняет выбранное значение поля даты. У меня есть форма с таким полем, как:

<? echo $this->Form->control('deadline', ['class' => 'form-control text-form-control', 'type' => 'datetime']); ?>

Я могу редактировать и изменять дату с помощью существующей задачи в базе данных, но при добавлении новой задачи у меня возникает ошибка массажа:

Cannot convert value of type `string` to integer
InvalidArgumentException

В настольной модели у меня есть:

<?php
 public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) {
    foreach (['deadline'] as $key) {
        if (isset($data[$key]) && is_array($data[$key])) {
            $data[$key] = strtotime($data[$key]['year'] . '-' . $data[$key]['month'] . '-' . $data[$key]['day'] . ' ' . $data[$key]['hour'] . ':' . $data[$key]['minute']);
        }
    }
}
?>

Трассировки стека:

Error: [InvalidArgumentException] Cannot convert value of type `string` to integer (\vendor\cakephp\cakephp\src\Database\Type\IntegerType.php:72)
#0 \vendor\cakephp\cakephp\src\Database\Type\IntegerType.php(91): Cake\Database\Type\IntegerType->checkNumeric('2020-01-23 15:5...')
#1 \vendor\cakephp\cakephp\src\Database\TypeConverterTrait.php(36): Cake\Database\Type\IntegerType->toDatabase('2020-01-23 15:5...', Object(Cake\Database\Driver\Mysql))
#2 \vendor\cakephp\cakephp\src\Database\Statement\PDOStatement.php(68): Cake\Database\Statement\StatementDecorator->cast('2020-01-23 15:5...', 'integer')
#3 \vendor\cakephp\cakephp\src\Database\ValueBinder.php(146): Cake\Database\Statement\PDOStatement->bindValue('c7', '2020-01-23 15:5...', 'integer')
#4 \vendor\cakephp\cakephp\src\Database\Connection.php(332): Cake\Database\ValueBinder->attachTo(Object(Cake\Database\Statement\MysqlStatement))
#5 \vendor\cakephp\cakephp\src\Core\Retry\CommandRetry.php(67): Cake\Database\Connection->Cake\Database\{closure}()
#6 \vendor\cakephp\cakephp\src\Database\Connection.php(336): Cake\Core\Retry\CommandRetry->run(Object(Closure))
#7 \vendor\cakephp\cakephp\src\Database\Query.php(218): Cake\Database\Connection->run(Object(Cake\ORM\Query))
#8 \vendor\cakephp\cakephp\src\ORM\Table.php(2129): Cake\Database\Query->execute()
#9 \vendor\cakephp\cakephp\src\ORM\Table.php(2021): Cake\ORM\Table->_insert(Object(App\Model\Entity\Task), Array)
#10 \vendor\cakephp\cakephp\src\ORM\Table.php(1934): Cake\ORM\Table->_processSave(Object(App\Model\Entity\Task), Object(ArrayObject))
#11 \vendor\cakephp\cakephp\src\ORM\Table.php(1639): Cake\ORM\Table->Cake\ORM\{closure}()
#12 \vendor\cakephp\cakephp\src\Database\Connection.php(737): Cake\ORM\Table->Cake\ORM\{closure}(Object(Cake\Database\Connection))
#13 \vendor\cakephp\cakephp\src\ORM\Table.php(1640): Cake\Database\Connection->transactional(Object(Closure))
#14 \vendor\cakephp\cakephp\src\ORM\Table.php(1935): Cake\ORM\Table->_executeTransaction(Object(Closure), true)
#15 \src\Controller\TasksController.php(65): Cake\ORM\Table->save(Object(App\Model\Entity\Task))
#16 \vendor\cakephp\cakephp\src\Controller\Controller.php(609): App\Controller\TasksController->add()

1 ответ

Хорошо, не очень уверен, поможет ли это вам, но я могу придумать несколько вещей, которые вы могли бы попробовать.
Я думаю, вы слишком много стараетесь, вместо того, чтобы полагаться на cakePHP 3 (поверьте, я чувствую вас там, потому что у меня самого есть такая привычка).
Насколько вы добавляете поведение Timestamp в свою таблицу, добавляя это в свою инициализацию таблицы:

          public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->addBehavior('Timestamp');//<--- this one here
         ......
    }

Вам не нужно заботиться о преобразовании даты и времени при условии, что для сбора данных в вашем представлении использовался правильный элемент управления (как и у вас).
Обратите внимание, что вам не нужно указывать тип для поля крайний срок, если он определен в базе данных как тип DateTime (как кажется, вы это сделали, поскольку вы пытаетесь преобразовать во что-то вроде 'ГГГ-ММ-ДД HH: ii: SS ', что очень похоже на SQL DateTime).
CakePHP 3 будет выводить его и действовать в соответствии со схемой базы данных.

Подводя итог, я бы попробовал:

  • Добавьте код, который я написал выше
  • Удалите код beforeMarshal
  • Наконец (но необязательно) измените строку формы для элемента управления для «крайнего срока» на:
      <? echo $this->Form->control('deadline', ['class' => 'form-control text-form-control']); ?>

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

      $data = $this->request->getData();

И как выглядит Entity после исправления данных с помощью

      $entity = $this->YourModel->patchEntity($youEntityModel, $data);

Если вы отметите $entity с чем-то вроде debug ($entity), вы сможете увидеть свойство 'errors', и если есть что-то странное, например, неправильно инициализированные или неверно отформатированные данные и где, когда cakePHP пытается отформатировать данные из перед сохранением в подходящий объект Entity.

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