企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 前言 ***** 在使用thinkphp框架开发中,遇到很多需要捕获异常的情况 * 如往数据库插入数据时如果异常则抛出:数据插入失败, * 请求第三方接口异常时候抛出:接口异常,原因:XXXX * 其他更多场景 ```php <?php //我们捕获异常的代码可能是这样的 try { $user = new User; $user->name = 'thinkphp'; $user->email = 'thinkphp@qq.com'; $user->save(); } catch (\Exception $e) { return json(['code' => -1, msg => '用户添加失败:' . $e->getMessage()]); } } ``` 那除了不停的try catch之外,是否有更加便捷高效的方法来统一捕获这些异常,并且能够在第一时间自动利用微信消息通知我们呢?答案是肯定的.本文将与大家分享thinkphp5.1的异常处理接管以及使用微信企业号实时通知程序异常告警,以便开发者在第一时间排查问题并做出对应处理. # Thinkphp5.X 之异常自定义接管 ***** thinkphp框架为我们提供了一个非常便利的功能就是异常自定义接管,首先我们为什么要自己去接管异常,有何使用场景? * 例如在开发API接口时希望只要程序有异常时对前端统一抛出: {code:-1,msg:"具体错误信息"}, 方便前端给用户弹出对应提示语 . * 即上文提到的希望在程序有异常时通知开发者,以便主动做出对应处理,不必等待用户主动反馈报错再去排查. 首先建议读者先仔细阅读 [ThinkPHP5.1完全开发手册之异常处理章节]( https://www.kancloud.cn/manual/thinkphp5_1/354092), 我们先在应用配置文件app.php中配置参数 exception_handle ![](https://box.kancloud.cn/00d82cdbf7a692ccd2aa468a6df089dd_1566x389.jpg) app\common\controller\Handle 异常接管类的文件可能如下 ```php <?php namespace app\common\controller; use Exception; use think\exception\Handle as TpHandle; use think\exception\HttpException; use think\exception\ValidateException; use think\console\Output as ConsoleOutput; class Handle extends TpHandle { protected function alarm(Exception $exception) { try { //将异常所在文件,以及行数 通知开发者 方便排查异常原因 $errmsg = $exception->getMessage(); $data = [ 'title' => '程序异常通知', 'keyword1' => "file: " . $exception->getFile() . ';line:' . $exception->getLine(), 'keyword2' => "message: " . $errmsg, ]; //发送微信企业消息 通知开发者 下文会详细讲解 send_workweixin_textcard($data); } catch (Exception $e) { //需手动捕获异常,防止上文异常后死循环 trace('消息发送失败:'. $e->getMessage() . $errmsg, 'error'); } } public function report(Exception $e) { //异常通知 $this->alarm($e); //交由Thinkphp框架继续处理 parent::report($e); } //在CLI命令行模式有异常时将由此方法接管 /** * @param Output $output * @param Exception $e */ public function renderForConsole(ConsoleOutput $output, Exception $e) { //异常通知 $this->alarm($e); //交由Thinkphp框架继续处理 parent::renderForConsole($output, $e); } //在普通模式有异常时将由此方法接管 /** * @param Exception $e */ public function render(Exception $e) { try { $errmsg = $e->getMessage(); $data = [ 'title' => '程序异常通知', 'keyword1' => "url: " . $url, 'keyword2' => "message: " . $errmsg, ]; //发送微信企业消息 通知开发者 下文会详细讲解 send_workweixin_textcard($data); $data = [ 'code' => intval($e->getCode()) ?: -1, 'msg' => $e->getMessage(), ]; //因本项目是API接口开发 统一返回固定格式 return json($data); } catch (Exception $e) { //需手动捕获异常,防止上文异常后造成死循环 trace('消息发送失败'. $e->getMessage(), 'error'); } //交由Thinkphp框架继续处理 return parent::render($e); } } ``` > 让我们测试一下 当程序异常时会如何捕获异常,我们尝试测试如下代码: ```php <?php public function index() { //未定义变量 直接echo 将抛出异常 echo $b; } ``` > 我们通过url访问此方法看如何提示 ![](https://box.kancloud.cn/7a16a7bd0f5ecd4b749017834d889fa2_519x149.png) 至此,我们已经实现了统一捕获框架异常并按照统一格式抛出,极其适合API接口开发的项目, 这样永远抛出的都是一个合法的json且可被对方识别.方便将异常返回给前端. # 利用微信企业号实时通知程序异常 ***** 1. 首先我们需要申请微信企业号,[点击进入企业号官网]( https://work.weixin.qq.com),注册的流程将不再做过多讲解. 2. 创建应用以及获取企业ID[登录企业微信后台后点我查看](https://work.weixin.qq.com/wework_admin/frame#profile)和secret密钥 以获取access_token, 开发文档可参考 [点击进入开发文档]( https://work.weixin.qq.com/api/doc#10013/第三步:获取access_token) 3. 组转指定格式数据给对应开发者微信号推送消息 ![](https://box.kancloud.cn/8f3ab4a5877f059116a123949854da2c_1423x1015.jpg) ![](https://box.kancloud.cn/d7691a80f646839a423a0976a500b024_1347x865.jpg) ![](https://box.kancloud.cn/2020cecd83d1b46cc08619344a315da6_1342x435.jpg) 因本人实际项目中使用的是封装的比较复杂方法,故附上伪代码,仅供参考 提供思路 ```php <?php public function send_workweixin_textcard($data) { $corpid = '换成您wx开头的企业ID'; $agentid = '换成您的应用ID'; $access_token = $this->get_access_token(); $url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' . $access_token; $description = "<div class=\"normal\">" . $data['keyword1'] . "</div><br>"; if (!empty($data['keyword2'])) { $description .= "<div class=\"highlight\">" . $data['keyword2'] . "</div><br>"; } $post_data = [ 'corpid' => $corpid, 'data' => [ 'touser' => 'xieyongfa',//成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送 'msgtype' => 'textcard', 'agentid' => $agentid, 'textcard' => [ 'title' => $data['title'], 'description' => $description, ], ] ]; curl_post($url,json_encode($post_data)); //发送消息 curl post请求请自行百度实现 } protected function get_access_token() { $corpid = '换成您wx开头的企业ID'; $corpsecret = '换成您的应用密钥'; $url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' . $corpid . '&corpsecret=' . $corpsecret; $json = curl_get($url); //curl 方法请自行百度 $result = json_decode($json, true); if (isset($result['errcode']) || $result['errcode'] === 0) { return $result['access_token']; //todo实际场景中请做好缓存逻辑 } else { throw new \Exception('access_token获取异常' . $result['errmsg'], $result['errcode']); } } ``` 效果图:这样我们即可快速定位到异常的文件以及行数 ![](https://box.kancloud.cn/99d1a53ddb011f7626107fb23017fbec_1242x2208.png =250x440) # 后记 ## 开发帮助及交流 如您对本文感兴趣想与我联系交流 您可以 + 邮件至:xieyongfa@ecarde.cn + QQ:2392523899 [点我聊天](http://wpa.qq.com/msgrd?v=3&uin=2392523899&site=qq&menu=yes&from=message&isappinstalled=0) + 微信交流 ![](https://box.kancloud.cn/b74285a950ce81e3cb782f02eb118d59_752x974.jpg =300x389)