ThinkPHP自身不内置RPC客户端,应避免手写cURL;推荐方案是Swoole+JSON-RPC自建轻量闭环,或抽离为独立Composer包共享逻辑,禁用直接require跨应用代码。
ThinkPHP 里怎么用 RPC 调用其他应用?别碰
手写请求
直接上结论:ThinkPHP 自身不内置 RPC 客户端,硬用
或
发 HTTP 请求调远程服务,等于把 RPC 当成裸 API 用——丢了服务发现、超时熔断、序列化协议这些关键能力。
真正可行的轻量级方案是:用
或
做底层通信,但 PHP 端只承担「客户端」角色,服务端交给 Go/Java 写;或者退半步,用 ThinkPHP +
+
协议自建最小闭环。
别在控制器里写
调另一个 TP 应用的
—— 这不是 RPC,是 HTTP 轮询,没重试、没连接池、没上下文透传
如果两个应用都用 ThinkPHP,优先走
(需开启协程),比原生
低延迟且可复用连接
的
扩展只是注册中心包装,不解决通信层问题;真要轻量,直接手写
类,用
+
就够用
多个 ThinkPHP 应用之间共享服务逻辑,为什么不能直接 require 公共目录?
因为「共享代码」不等于「共享运行时」。直接
另一个应用的
,会触发自动加载冲突、容器绑定覆盖、配置环境错乱。
常见错误现象:
(命名空间对不上)、
(依赖注入容器没初始化)。
立即学习
“
PHP免费学习笔记(深入)
”;
多应用共用逻辑,必须抽成独立 Composer 包,用
引入,而不是用
或
包内不能依赖
的具体版本,否则 A 应用用 tp6.3、B 应用用 tp6.2,就会因
接口微变而报错
如果只是临时解耦,可用「接口定义 + 本地桩实现」:在公共包里放
,各应用自己实现,调用方只依赖接口,不感知实现来源
用 Swoole 启动 ThinkPHP 微服务时,
和
哪个更稳?
是 TP 官方封装的 Swoole 启动命令,但它默认禁用协程 Hook、不支持热 reload、路由中间件加载顺序和 FPM 模式不一致——线上出问题很难排查。
真实场景下,建议绕过
,手写启动脚本,直接操作
。
必须手动调用
,否则
查询会阻塞整个进程
不要在
回调里直接 new 控制器——TP 的容器、请求对象、配置都是 FPM 生命周期设计的,Swoole 下要重新 bind
静态资源(
下的 JS/CSS)别让 Swoole 处理,Nginx 前置代理更可靠;否则容易出现
且无法调
调试跨应用调用失败,第一步该看哪几个日志和返回值?
别急着改代码,先确认通信链路是否通、序列化是否对、上下文是否丢。
典型错误:
(Nginx 到 Swoole 断连)、
(JSON 返回体被 HTML 错误页污染)、
(目标服务根本没起来或端口不对)。
查目标服务的
,不是调用方的
—— RPC 失败大概率卡在对方入口
用
直连目标服务,看响应头有没有
,body 是否为合法 JSON
在调用方加一行
,确认没被中间件(比如 CORS、TraceId 注入)意外截断或改写
微服务不是把单体拆成多个 TP 应用就完事,最关键的其实是边界控制:哪些逻辑必须隔离成服务,哪些其实用本地队列+事件就能解耦。RPC 调用一旦泛滥,连 traceID 都串不起来,后面查问题就只剩翻日志猜了。
curlcurlfile_get_contentsgRPCThriftSwooleJSON-RPCcurl_init()/api/user/infoSwoole\Coroutine\Http\ClientcURLtp6think-serviceJsonRpcClientPOSTapplication/jsonrequireapp/service/UserService.phpClass 'app\service\UserService' not foundCall to a member function xxx() on nullcomposer require vendor/common-servicealiasextend_paththinkphp/frameworkthink\ContainerUserInterfacethink runswoole_http_serverthink runthink runSwoole\Http\ServerSwoole\Runtime::enableCoroutine(true)Db::onRequestpublic/413 Request Entity Too Largeclient_max_body_size502 Bad GatewayParseError: syntax error, unexpected '{'Connection refusedserver.logruntime/logcurl -v http://127.0.0.1:8081/api/rpcContent-Type: application/jsonvar_dump($response->getBody()->getContents());