zl程序教程

您现在的位置是:首页 >  后端

当前栏目

PHP:Laravel cast array json数据存数据库时unicode 编码问题和update更新不触发数据转换

2023-09-14 09:07:18 时间

问题描述

Model示例

class UserModel extends Model
{
    protected $table = 'tb_user';

    protected $casts = [
        'alias'            => 'array'
    ];
}

直接存alias 字段,数据库会显示unicode码

["\u80c3\u75db\u554a"]

问题解决

方式一:自定义属性

class UserModel extends Model
{

    public function setAliasAttribute($option)
    {
        $this->attributes['alias'] = json_encode($option, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }
}

方式二:继承覆写

class UserModel extends Model
{
    protected $table = 'tb_user';

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

    // 覆盖asJson方法
    protected function asJson($value)
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

方式三:trait复用

trait UnicodeJsonTrait
{
    /**
     * 序列化json
     * @param $value
     * @return false|string
     */
    protected function asJson($value)
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

直接在基类里使用(也可以在基类中覆写)

class BaseModel extends Model
{
    use UnicodeJsonTrait;
}

继承基类

class UserModel extends BaseModel
{
    protected $table = 'tb_user';

    protected $casts = [
        'alias'            => 'array'
    ];
}

方式四:定义Cast子类

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class JsonCast implements CastsAttributes
{
    
    public function get($model, string $key, $value, array $attributes)
    {
        return json_decode($value, true);
    }

    public function set($model, string $key, $value, array $attributes)
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

使用

<?php

namespace App\Models;

use App\Casts\JsonCast;
use Illuminate\Database\Eloquent\Casts\Attribute;

class UserModel extends Model
{
    protected $table = 'tb_user';

    protected $casts = [
        'alias'            => JsonCast::class,
    ];
}

update不生效

save/create可以正常触发数据转换,update的时候需要注意

平常更新数据是这样的

$this->where(xxx)->update(xxx)

需要注意的是,这样写不会触发updating和updated事件

需要先获取模型再进行对应的操作,才能触发对应的模型事件

$this->where(xxx)->first()->update(xxx)

// 或
$this->find(xxx)->update(xxx)

参考文章