ray() 不是 dd() 的平替,而是专为不中断流程设计的异步调试工具,通过 HTTP 发送数据至本地 Ray 客户端,不影响脚本执行,适用于 API、队列、中间件及 Artisan 命令等所有 PHP 场景。

ray() 不是 dd() 的平替,它是专为「不中断流程」设计的异步调试工具,适合 API、队列、中间件、命令行等所有场景——只要能写 PHP 代码的地方,ray() 都能输出,且不影响后续执行。
为什么 ray() 在 API 和队列里能用而 dd() 不能
dd() 是同步阻断式操作:它 dump 数据后立刻 die,在 HTTP 响应中会破坏 JSON 格式,在队列里会让 worker 进程直接退出;而 ray() 默认通过 HTTP 发送数据到本地 Ray 应用(macOS/Windows/Linux 桌面客户端),完全不干涉当前脚本生命周期。
- API 接口里调用
ray($user)→ 前端仍收到干净的200 { "data": {...} },同时你在 Ray 客户端看到结构化变量 - 队列任务里写
ray('processing', ['id' => $job->id]);→ job 正常完成,日志和时间线都保留在 Ray 历史中 - Artisan 命令中用
ray()->table($users);→ 终端无干扰,数据以表格形式出现在 Ray 窗口
安装后必须配对的三件事
装完 composer require spatie/laravel-ray --dev 并 php artisan vendor:publish --provider="Spatie\Ray\RayServiceProvider" 后,以下三点不配齐,ray() 就是“静默失效”:
-
RAY_HOST必须设为运行 Ray 客户端的机器 IP(Docker 环境填host.docker.internal,WLS2 填 Windows 主机 IP,本地开发填127.0.0.1) -
RAY_PORT默认是23517,确保 Ray 客户端监听端口与此一致(Ray 设置页可改) -
APP_DEBUG=true必须生效 ——ray()在APP_DEBUG=false下默认禁用,不是 bug,是设计
ray() 的真实调试姿势,不是只 dump 变量
它本质是个轻量级「远程控制台」,支持链式调用和上下文标记,比日志更直观,比 Xdebug 更快定位:
- 加标签区分来源:
ray('auth')->showRequest();会附带当前请求 URL、method、headers - 标时间线:
ray()->startMeasure('cache-fetch');+ray()->stopMeasure('cache-fetch');显示耗时 - 查 SQL:
ray()->showQueries();放在控制器开头,后续所有 Eloquent 查询都会被捕获并高亮显示 - 临时禁用某处:
ray()->send(false)->info('this wont appear');
容易被忽略的兼容性坑
Ray 依赖 socket 连接,默认走 TCP;某些共享主机、CI 环境或严格防火墙下会失败,但不会报错,只会“没反应”:
- CI 测试中想用 Ray?改用
ray()->send(false)->html(...)或直接切回Log::debug() - PHP 8.2+ 使用
ray()->measure()时,若闭包里含__invoke对象,可能触发反射异常 —— 改用命名函数封装再测 - 多租户应用中,
ray()默认按 PHP 进程隔离,但如果你用了 Swoole 或 RoadRunner,需手动调用ray()->clearAllContexts();避免跨请求污染


















