自定义函数本身不构成链路,真正可链式调用的是ORM查询对象;success()和error()返回Response实例,无where()等方法,无法链式;实现链式需函数返回支持return $this的对象实例。

自定义函数本身不构成“链路”,所谓“链路”是误用概念;TP5 中真正可链式调用的是 ORM 查询对象(如 Db::name('user')),而普通函数返回值决定是否能链式调用——关键看它是否返回自身实例或支持后续方法的对象。
为什么 success() 和 error() 不能链式调用
这两个是典型响应辅助函数,返回的是 json() 执行结果(字符串或 Response 对象),不是 Query 或 Builder 实例:
-
success()内部调用json($data),最终返回Response实例 —— 它没有where()、find()这类方法,无法继续链式操作 - 试图写
success('ok')->where(...)会报Fatal error: Call to undefined method think\Response::where() - 它们的设计定位是「终止流程并输出」,不是「构建查询」
想实现链式调用,必须返回支持链式的方法对象
例如自定义一个查询构造器包装函数,让它返回 Query 实例:
function userQuery() {
return Db::name('user');
}
这样就能链式使用:
userQuery()->where('status', 1)->order('id desc')->select();
- 核心是函数体最后一行必须是「返回一个具备链式方法的对象」
- 不能在中间加
return json(...)或echo,否则链断裂 - 若需附加默认条件,可在返回前调用:
return Db::name('user')->where('deleted', 0);
常见踩坑:混淆「函数调用链」和「对象方法链」
有人尝试这样写:
function a() { return 'a'; }
function b() { return 'b'; }
a()->b(); // ❌ PHP 会报 "Call to a member function b() on string"
- PHP 函数返回标量(string/int/bool)或数组时,无法调用方法
- 只有返回对象(且该对象有对应 public 方法)才能链式调用
- TP5 的
Db::name()能链式,是因为它返回的是think\db\Query实例,而该类每个方法都return $this;
真正要“写链路”,重点不在函数怎么定义,而在返回值类型和对象内部是否支持 return $this。硬给 success() 加链式,等于让 JSON 响应去执行数据库查询——逻辑错位,也违背分层职责。

















