开发学院

您的位置:首页>技术文章>正文

技术文章

Codeigniter 4实体属性转换为未自动序列化的数组

开发学院2022-04-12 13:52:18

  我试图将一个实体属性转换成一个数组,以便它自动序列化。

  该实体的设置如下

\App\Entities\Submission.php

<?php

namespace App\Entities;
use CodeIgniter\Entity;

class Submission extends Entity
{

 protected $casts =[
   'field2' => 'array'
 ];

}

  然后在控制器中,我创建了一个新的实体,用构造函数填充它

<?php
$allowedFromPost = [
'field1'=>'value1',
'field2'=>[0,1],
];

$submission = new \App\Entities\Submission($allowedFromPost);
?>

  此时转储提交(var_dump())显示field2是一个数组,它不是序列化的。

 ["attributes":protected]=>
  array(2) {
    ["field1"]=>
    string(6) "value1"
    ["field2"]=>
    array(2) {
      [0]=>
      int(0)
      [1]=>
      int(1)
    }
  }

  如果我这样做

$allowedFromPost = [
'field1'=>'value1',
'field2'=>[0,1],
];

$submission = new \App\Entities\Submission($allowedFromPost);
$submission->field2 = $submission->field2;

  然后var_dump,field2被正确序列化。

  ["attributes":protected]=>
  array(2) {
    ["field1"]=>
    string(6) "value1"
    ["field2"]=>
    string(22) "a:2:{i:0;i:0;i:1;i:1;}"
  }

  出于某种原因,似乎使用构造函数填充不会自动序列化,我必须手动设置字段。我做错什么了吗?

  这导致的问题是,当我试图将那个实体插入数据库时,它抛出一个错误:

mysqli_sql_exception Operand should contain 1 column(s)

  当我展平数组时,这种情况就消失了(首先,只留下一个值进行测试,然后使用上面的方法)

解决方案

  这是一个核心代码的问题。fill()(和构造函数)未配置为使用__set(),因此未发生自动序列化。

  目前使用下面的解决方法,但将来很可能不需要它。

  将此添加到实体中:

public function __construct($arr) {
   $this->field2 = $arr['field2'];
}

  控制器

$allowedFromPost = [
'field1'=>'value1',
'field2'=>[0,1],
];

$submission = new \App\Entities\Submission($allowedFromPost);
var_dump($submission)

  结果

["attributes":protected]=>
  array(2) {
    ["field1"]=>
    string(6) "value1"
    ["field2"]=>
    string(22) "a:2:{i:0;i:0;i:1;i:1;}"
  }

  根据CI文档,您需要在初始化其模型后设置它:

<?php namespace App\Entities;

use CodeIgniter\Entity;

class User extends Entity
{
    protected $casts => [
        'options' => 'array',
                'options_object' => 'json',
                'options_array' => 'json-array'
    ];
}

$user    = $userModel->find(15);
$options = $user->options;

$options['foo'] = 'bar';

$user->options = $options;
$userModel->save($user);