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

如何在Laravel中查询MariaDB JSON列含Unicode字符的键

问题描述

模型包含JSON类型属性,当JSON键使用希腊字符(如μ)时,MariaDB会将其自动编码为Unicode转义序列(例如μ存储为\u03bc)。通过Eloquent读取数据时字符会自动还原,但使用whereJsonContainsKey查询含这类非标准字符的JSON键时,无法匹配到记录;查询常规字符键(如k)则正常。

数据创建代码:

$unit = Unit::factory()->create();
$unit->name = 'Some name';
$unit->unit = 'Ω';
$unit->prefixes = ['μ' => 0.000001, 'k' => 1000, 'M' => 1000000];
$unit->save();

查询示例:

// 返回null,无法命中记录
$u = Unit::whereJsonContainsKey('prefixes->μ')->first();

// 正常返回目标数据
$u = Unit::whereJsonContainsKey('prefixes->k')->first();
解决方案

方法1:直接用原始SQL匹配Unicode转义序列

利用MariaDB的JSON_CONTAINS_PATH函数,直接传入Unicode转义后的键进行查询:

$u = Unit::whereRaw("JSON_CONTAINS_PATH(prefixes, 'one', '$.\\u03bc')")->first();

注:PHP字符串中需双反斜杠转义,确保SQL语句最终传入$.\u03bc。

方法2:手动转义字符后使用whereJsonContainsKey

先将目标字符转换为Unicode转义格式,再传入whereJsonContainsKey:

// 手动转义μ为Unicode序列
$escapedKey = '\u03bc';
$u = Unit::whereJsonContainsKey("prefixes->{$escapedKey}")->first();

如果需要通用处理任意非ASCII字符,可以封装转义函数:

function jsonEscapeUnicode(string $str): string {
    return preg_replace_callback('/[^\x00-\x7F]/u', function ($match) {
        $char = mb_convert_encoding($match[0], 'UTF-16BE', 'UTF-8');
        return sprintf('\u%04s', bin2hex($char));
    }, $str);
}

// 转义μ后查询
$escapedMu = jsonEscapeUnicode('μ');
$u = Unit::whereJsonContainsKey("prefixes->{$escapedMu}")->first();

方法3:通过JSON_KEYS提取键后匹配

使用JSON_KEYS提取JSON的所有键,再用JSON_SEARCH检查目标字符是否存在:

$u = Unit::whereRaw("JSON_SEARCH(JSON_KEYS(prefixes), 'one', ?)", ['μ'])->first();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:57:12