You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2处理二进制数据方法:创建ActiveRecord及带UNHEX的查询

Yii框架下二进制字段表的ActiveRecord实现与查询方案

1. 创建对应表的基础ActiveRecord模型

首先在模型目录下创建对应digiid_callback表的模型类,基础写法如下:

namespace app\models;

use yii\db\ActiveRecord;

class DigiidCallback extends ActiveRecord
{
    // 绑定对应的数据表名
    public static function tableName()
    {
        return 'digiid_callback';
    }
}

这个基础模型可以直接完成基础CRUD,但因为表中存在BINARY类型的二进制字段,直接读写会出现乱码、查询匹配失败的问题,需要额外做字段值的转换处理。

2. 配置二进制字段的自动转换逻辑

通过模型内置的生命周期钩子,可以实现二进制数据和可读十六进制字符串的自动转换,业务层不需要每次手动调用HEX/UNHEX函数:

namespace app\models;

use yii\db\ActiveRecord;

class DigiidCallback extends ActiveRecord
{
    public static function tableName()
    {
        return 'digiid_callback';
    }

    // 数据从库中读取完成后,自动把二进制字段转为十六进制字符串
    public function afterFind()
    {
        parent::afterFind();
        if ($this->nonce !== null) {
            $this->nonce = bin2hex($this->nonce);
        }
        if ($this->address !== null) {
            $this->address = bin2hex($this->address);
        }
    }

    // 数据写入数据库前,自动把十六进制字符串转回二进制格式
    public function beforeSave($insert)
    {
        if (!parent::beforeSave($insert)) {
            return false;
        }
        if ($this->nonce !== null) {
            $this->nonce = hex2bin($this->nonce);
        }
        if ($this->address !== null) {
            $this->address = hex2bin($this->address);
        }
        return true;
    }
}

配置完成后,业务代码中读写nonce、address字段都直接用十六进制字符串即可,不需要关心底层的二进制存储逻辑。

3. 实现带UNHEX函数的二进制条件查询

如果没有做上面的全局自动转换,或者需要直接用十六进制格式的nonce值查询,不能直接调用findOne()传参——默认的查询逻辑会把传入值当普通字符串做等值匹配,无法命中二进制存储的字段值,需要用数据库表达式明确调用UNHEX函数:

// 传入的$nonceHex为十六进制格式的nonce值
$nonceHex = 'a1b2c3d4e5f67890';
$record = DigiidCallback::find()
    ->where(['nonce' => new \yii\db\Expression('UNHEX(:nonce)', [':nonce' => $nonceHex])])
    ->one();

如果这类查询使用频率高,可以直接在模型中封装静态查询方法简化调用:

public static function findByNonce(string $nonceHex)
{
    return static::find()
        ->where(['nonce' => new \yii\db\Expression('UNHEX(:nonce)', [':nonce' => $nonceHex])])
        ->one();
}

后续业务中直接调用DigiidCallback::findByNonce('你的十六进制nonce值')即可拿到对应记录。


注意事项

  • expire字段是TIMESTAMP类型,Yii会自动识别为时间格式,不需要额外做类型转换,可直接配合框架的自动时间戳功能使用
  • address字段允许为NULL,做二进制/十六进制转换前必须判空,否则会触发PHP类型警告
  • 禁止直接把十六进制字符串传入findOne()作为nonce的查询条件,否则会因为类型不匹配返回空结果

内容的提问来源于stack exchange,提问作者Matthew Cornelisse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:18:21