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.