Hyperf 3.x 不支持 whereJsonContains,需用 whereRaw 配合 JSON_CONTAINS(MySQL)或 @>(PostgreSQL);传参必须为合法 JSON 字符串,如 '"php"' 或 '{"action":"edit"}';小数据量可先查后 PHP 过滤,但不推荐;复杂场景建议改用关联表。

Hyperf 3.x 的 whereJsonContains 不可用
Hyperf 3.x 默认使用的 hyperf/database 基于 Laravel 9 的 Query Builder,但 whereJsonContains 是 Laravel 10+ 才正式引入的语法(Laravel 9 仅支持 whereJsonContains 的变体 whereJsonContains 在部分驱动下需手动启用,且底层依赖 MySQL 5.7+ 的 JSON_CONTAINS 函数)。Hyperf 3.x 的 Db 或 Model 查询中直接调用该方法会报 Call to undefined method 错误。
替代方案:用原生 JSON 函数 + whereRaw
MySQL 5.7+ 支持 JSON_CONTAINS、JSON_EXTRACT 等函数,PostgreSQL 则用 @> 或 ? 操作符。Hyperf 3.x 中最稳妥的方式是用 whereRaw 显式拼写:
- 查 JSON 字段是否包含某个值(如
tags字段含字符串"php"):$users = User::whereRaw('JSON_CONTAINS(tags, ?)', ['"php"'])->get(); - 查 JSON 数组中是否包含某对象(如
permissions含{"action": "edit"}):User::whereRaw('JSON_CONTAINS(permissions, ?)', ['{"action": "edit"}'])->get(); - PostgreSQL 用户应改用:
User::whereRaw('permissions @> ?', ['{"action": "edit"}'])->get();
注意:JSON_CONTAINS 第二个参数必须是带双引号的 JSON 字符串(如 "php"),不能传 PHP 字符串 php;对象需完整 JSON 格式,键名也必须双引号包裹。
模型访问器 + whereIn 仅适用于小数据量场景
如果 JSON 字段结构简单(例如只存字符串数组),且结果集不大,可先取出再 PHP 层过滤:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 定义访问器(在 Model 中):
protected $casts = ['tags' => 'json']; // 自动转为 array
- 但
whereIn无法下推到 SQL,只能先查全量再array_filter:User::all()->filter(fn($u) => in_array('php', $u->tags ?? [])); - 这会把整张表加载进内存,千万级数据直接 OOM —— 仅适合配置类、权限类小表。
升级或自定义构建器的风险点
有人尝试通过扩展 Builder 注入 whereJsonContains 方法,但存在隐患:
- Hyperf 3.x 的
QueryBuilder未暴露grammar的完整扩展点,硬加方法可能在分页、关联预加载时失效; - 不同数据库语法不兼容(MySQL 的
JSON_CONTAINS和 PostgreSQL 的@>无法共用同一接口); - Hyperf 官方未承诺兼容 Laravel 10+ 的 JSON 查询语法,未来升级不一定平滑。
真正需要复杂 JSON 查询的场景,建议评估是否该把字段拆成关联表 —— 比强行用 JSON 查询更稳定、可索引、易调试。










