一、使用laravel框架自带的相关方法
用laravel框架中的DB类 自带的getQueryLog方法直接打印:
\Illuminate\Support\Facades\DB::connection()->enableQueryLog(); //开启执行日志,加在需要打印的SQL语句之前 $row = Supplier::query()->where('id', 18)->first(); echo "<pre>"; print_r(\Illuminate\Support\Facades\DB::getQueryLog()); //获取查询语句、参数和执行时间 exit;
打印结果类似如下:
Array ( [0] => Array ( [query] => select * from `supplier` where `id` = ? limit 1 [bindings] => Array ( [0] => 18 ) [time] => 3 //注意 这里的单位是毫秒 ) )
备注:貌似该方法是从laravel5加入的,我在 laravel 8.17.2 和 laravel 8.50.0 版本中用过,是可以的,至于laravel5、laravel6、laravel7、及后续的laravel更高的版本。。就自行去测试吧哈~
二、使用 Laravel Debugbar 调试器
调试神器 barryvdh/laravel-debugbar 这个扩展组件包,功能非常强大,不仅可以完整输出执行的sql语句(包括查询语句、sql语句的绑定参数、sql执行耗时的时间等),还能显示当前请求的路由信息、当前所加载的视图、显示所有事件、laravel版本及环境、显示 PHP include/require 的文件、显示配置文件的配置值、所有的log信息、使用的内存信息、等等等等。。。该扩展组件包 可以调试带web页面的(即:常见的web页面开发),也可以调试单纯的json api接口(但是,需要做一些额外的改动或配置。。感觉有些麻烦,不是很方便)
but!!warning!!!该扩展组件包非常消耗性能,建议只在开发环境中安装,线上生产环境请不要安装~~
2.1:安装(本文中该扩展组件包的版本号为:3.6.2)
laravel8.x版本的安装方式如下(因为我只在 laravel 8.17.2 和 laravel 8.50.0 版本中安装过):
composer require barryvdh/laravel-debugbar --dev #仅开发环境安装 composer require barryvdh/laravel-debugbar #备注:为什么要加上 --dev 参数? 如果没有加上 --dev,这会使Laravel debugbar被装在composer.json的require字段,而非require-dev字段,这会造成在正式线上的生产环境也会安装Laravel debugbar,这是不需要的。
浏览器刷新页面,即可看到底部的调试工具
然后运行如下的Artisan 命令将该扩展包的配置文件拷贝到 config 目录下(config/debugbar.php):
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
最终的效果图如下(这里我们 只看执行的sql语句):
如果想要关闭调试工具,可以设置 config/debugbar.php文件里面的 enabled 字段的值为 false 即可关闭
同时,也可以在相关代码文件中 临时进行开启或关闭
DebugBar::disable(); //启用 DebugBar::enable(); //关闭
特别提示:对于没有页面的纯api接口的调试。单独定义一个路由渲染一个给debugbar注入调试信息的view页面。然后你从任意地方(postman、app、前端项目)请求接口,点开右下角的调试按钮,通过筛选项过滤出你要查看的api请求就行。
可以添加一个单独的路由文件:
<?php //debugbar 调试工具页面 $router->get('debugbar', function () { if (env('APP_ENV') != 'production' && env('APP_DEBUG') === true) { return view('debug_tool.debugbar'); } abort(404); });
2.2、laravel5.x版本安装的相关设置
composer安装完成后,在 config/app.php文件中的 providers 数组里面进行 注册服务提供者。
注册如下服务提供者:
Barryvdh\Debugbar\ServiceProvider::class,
该扩展组件包的GitHub 地址:https://github.com/barryvdh/laravel-debugbar
该扩展组件包的packagist地址: https://packagist.org/packages/barryvdh/laravel-debugbar
关于该扩展组件包的安装及使用 也可以参考:https://www.cnblogs.com/guohong-hu/p/12548287.html
三、使用Laravel Telescope调试工具
相关软件版本信息如下:
Laravel版本:Laravel Framework 8.55.0
telescope版本:v4.10.2
Laravel Telescope 是Laravel官方 开发的一个专门为 Laravel 框架 打造的优雅的debug调试助手。Telescope可以为进入应用的请求、异常、日志、数据库查询、队列任务、邮件、通知、缓存操作、调度任务、变量打印等所有操作提供洞察明细功能,因此,它将成为你本地 Laravel 开发环境的又一绝佳伴侣。
Telescope 是由一系列监听器组成,这些 “监听器” 监听每个进入应用的请求,不管是来自 HTTP 、命令行、任务调度还是队列的。还是其它方式等等等等......
这些监听器可以捕获这些请求以及其相关数据信息 -- 例如数据库查询以及其执行时间,是否命中缓存,事件触发、邮件触发等等等等......
Telescope既可以调试web页面开发,也可以调试纯api接口开发,(和上面的laravel debugbar调试api接口不一样的是,laravel debugbar工具调试api接口的话 在安装部署好了后 需要单独设置一些相关东西 才可以调试api接口,而Telescope在部署好后 直接就能调试api接口 不需要在进行一些额外的单独设置)
上面说的 Laravel Debugbar 与 Telescope 进行对比的话 就是纯 UI界面(Laravel Debugbar) 和 重量级武器(Telescope)。所以Telescope最好也只在开发环境下进行安装部署,不要在线上生产环境进行安装部署,因为Telescope工具比较重,非常消耗性能,所以 最好不要在线上生产环境进行部署Telescope
安装完 Telescope 后,你可以访问 /telescope 来访问该应用
注意:Telescope 要求 Laravel 5.7.7+ 版本。可以通过 php artisan --version 查看自己的 Laravel 版本。建议至少在Laravel 5.8的环境中进行安装,本文是在Laravel 8.50.0 版本中进行部署的
3.1、Telescope工具的安装
。。。。。。怎么安装就先不说了。。。下面我会提供相关文章地址。。
3.2、调试页面效果(这里我们依然 只看执行的sql语句)
我用postman工具使用get方式 请求了www.domain.com/test地址,然后Telescope工具会监听到我们本次用postman发出的请求,并记录相关数据(比如:请求的地址、请求携带的参数、服务端所执行的具体sql语句等等等等......)
然后我们访问www.you-laravel-domain.com/telescope(具体域名根据实际情况换成你自己的,/telescope 是固定的访问格式)来查看Telescope工具为我们监听并记录本次请求的相关信息,效果图如下:
3.3、Telescope工具一些简单设置(比如 过滤掉 OPTIONS 请求)
telescope扩展组件安装完成后 通常会在 app/Providers/ 目录下生成一个 TelescopeServiceProvider.php 文件,这个文件就可以用代码设置一些Telescope工具的规则。另外 通常也会在 config目录下生成一个 telescope.php 文件 这个文件里面也可以配置一些规则 可以让telescope工具不记录指定规则的相关数据。
现在前后端分离模式开发很常见,因为跨域问题,所以请求相关后端api接口会引出OPTIONS请求 因为这种请求实际上对后端来说没啥作用,所以。。让telescope工具过滤掉OPTIONS请求(让telescope工具 不记录OPTIONS的请求相关信息),我们可以在 app/Providers/TelescopeServiceProvider.php 文件里面的 register()方法里面 使用filter闭包函数来过滤,过滤掉OPTIONS请求的核心代码如下:
Telescope::filter(function(IncomingEntry $entry){ if(request()->getMethod() == 'OPTIONS') { return false; } });
完整代码如下:
/** * Register any application services.(翻译中文为:注册应用服务) * * @return void */ public function register() { // Telescope::night(); $this->hideSensitiveRequestDetails(); Telescope::filter(function (IncomingEntry $entry) { //注意:代码必须写在 if ($this->app->environment('local')) 这个判断的上面 如果写在了下面 是不会生效的。 if(request()->getMethod() == 'OPTIONS') { //如果当前请求是 OPTIONS 则过滤掉 即 让telescope工具不进行记录该次请求的所有相关数据信息 return false; } //默认情况下,会记录local环境中的所有数据(请求、异常、日志、计划任务等)。当前环境是否是local 取决于 APP_ENV 的值设置的是什么 刚安装的laravel框架 默认情况下 .env 文件里面的 APP_ENV 就是设置的local if ($this->app->environment('local')) { return true; } /* * 将过滤 OPTIONS 请求的代码写在这里( * 即 写在了 if ($this->app->environment('local')) { return true; } ) 这个判断代码的下面 是不会生效的 */ //写在这里不会生效!!!!!! //if(request()->getMethod() == 'OPTIONS') { // return false; //} //下面这块儿代码 只会在 APP_ENV 没有设置为local时才会记录相关数据 return $entry->isReportableException() || $entry->isFailedRequest() || $entry->isFailedJob() || $entry->isScheduledTask() || $entry->hasMonitoredTag(); }); }
注意:上面代码的位置顺序,如果没有进行更改或者特殊处理的话 都是安装好的默认的情况下的时候 就按照这样写 就可以过滤掉 OPTIONS 请求了。
上面过滤OPTIONS请求的代码还可以这么写,使用注入的 $entry对象 来获取当前请求的各种详细数据 判断是否需要让 telescope 过滤掉当前请求(即 不记录本次请求的所有相关数据),代码如下:
/** * Register any application services.(翻译中文为:注册应用服务) * * @return void */ public function register() { // Telescope::night(); $this->hideSensitiveRequestDetails(); Telescope::filter(function (IncomingEntry $entry) { //dd($entry->content); //content属性是一个数组 里面包含了本次http请求状态码、uri、请求方式、控制器、中间件等各种详细数据 if($entry->content['response_status'] == 204) { return false; } if ($this->app->environment('local')) { return true; } return $entry->isReportableException() || $entry->isFailedRequest() || $entry->isFailedJob() || $entry->isScheduledTask() || $entry->hasMonitoredTag(); }); }
其它注意事项:
如果在app/Providers/TelescopeServiceProvider.php文件中的register()方法中写的过滤规则没有对telescope生效的话,除了检查register()中写的代码问题,还要检查 config/app.php 文件中的 providers数组中,是否注册了telescope为服务提供者,如果没有,则在providers数组中注册telescope为服务提供者,即 在providers数组中 追加 App\Providers\TelescopeServiceProvider::class
Telescope工具的相关资料如下:
Laravel8.x版本中的Telescope工具的文档:https://learnku.com/docs/laravel/8.x/telescope/9424
视频教程:https://learnku.com/courses/laravel-package/2019/telescope/2492
本地开发调试解决方案:Laravel Telescope:https://laravelacademy.org/index.php/post/9687.html
Laravel Telescope 完美的应用调试工具:https://learnku.com/laravel/t/19013
如何更好地使用 telescope:https://learnku.com/articles/45653
Telescope | 后盾人:https://doc.houdunren.com/%E6%89%8B%E5%86%8C/laravel/10%20%E5%AE%98%E6%96%B9%E6%89%A9%E5%B1%95%E5%8C%85/7%20Telescope.html#介绍
基于Laravel Telescope提供本地调试解决方案:https://laravelacademy.org/post/22039#toc-0
https://cloud.tencent.com/developer/ask/sof/660093?from=16139
https://www.zhblog.net/qa/entries-in-laravel.html
四、使用laravel框架内置的“监听查询事件”
该种方法(监听查询事件) 本文所使用的Laravel框架版本号为:Laravel Framework 8.55.0
如果你想监控程序执行的每一个 SQL 查询,你可以使用 listen 方法。这个方法对于记录查询或调试非常有用。你可以在 服务提供器 中注册你的查询监听器。
这里我就不创建单独的监听器了,直接修改 app/Providers/EventServiceProvider.php 文件中的boot()方法即可,直接把监听laravel框架执行的sql语句代码写在这个方法里面即可,最终 boot()方法中的 监听框架执行的sql语句代码 如下所示:
/** * Register any events for your application. * * @return void */ public function boot() { //监听laravel框架执行的sql语句 并记录到log日志文件中 DB::listen(function(QueryExecuted $event){ $sql = $event->sql; //执行的sql语句 $bindings = $event->bindings; //sql语句对应绑定的sql值 $time = $event->time; //sql执行的时间 $bindings = array_map(function($binding){ if(is_string($binding)) { return "'$binding'"; //如果$binding是字符串类型 则要将$binding的左右两边拼接上'' 即 字符串=》 '字符串' } else if($binding instanceof \DateTime) { return $binding->format("'Y-m-d H:i:s'"); //如果$binding是一个DateTime对象 则格式化时间 并在左右俩边拼接上'' } else { return $binding; //直接返回$binding原本的值 } }, $bindings); $sql = str_replace('?', '%s', $sql); //将sql语句中的?换成%s $sql = sprintf($sql, ...$bindings); //将$bindings数组中的每一个元素替换掉$sql中的%s的位置 Log::info("sql_log", ["sql" => $sql, "execute_time" => $time]); //将最终生成的sql语句写入到log日志文件中 }); }
尾声:
从如何输出Laravel框架执行的sql语句 到 引导出2个调试 Laravel 框架的debug工具,真是nice啊~ 哈哈哈哈哈哈
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
精彩评论