Thinkphp 在api开发中异常返回依然是html的解决方式


Posted in PHP onOctober 16, 2019

现在谁不开发接口的呢?但是在接口开发过程中,报错误异常后居然返回错误的信息依然是html信息!TP官方也不知道为啥不添加,说好的为接口而生,我的解决方案也很简单,把系统的异常处理类复制出来,去掉模板相关,直接以json方式输出

下面是解决方案:

1:按照TP扩展异常的方式引用这个文件

https://www.kancloud.cn/manual/thinkphp5_1/354092

// 判断默认输出类型
// $app 是配置数组
if ($app['default_return_type'] == 'json') {
 // 异常处理handle类 留空使用 \think\exception\Handle
 $app['exception_handle'] = '\\app\\common\\exception\\JsonException';
}
return $app;

异常处理类:

<?php

 namespace app\common\exception;


 use Exception;
 use think\exception\ErrorException;
 use think\exception\Handle;
 use think\exception\HttpException;
 use think\console\Output;
 use think\Container;
 use think\Response;


 class JsonException extends Handle
 {
  protected $render;
  protected $ignoreReport = [
   '\\think\\exception\\HttpException',
  ];

  public function setRender($render)
  {
   $this->render = $render;
  }

  /**
  * Report or log an exception.
  *
  * @access public
  * @param \Exception $exception
  * @return void
  */
  public function report(Exception $exception)
  {
   if (!$this->isIgnoreReport($exception)) {
   // 收集异常数据
   if (Container::get('app')->isDebug()) {
    $data = [
     'file' => $exception->getFile(),
     'line' => $exception->getLine(),
     'message' => $this->getMessage($exception),
     'code' => $this->getCode($exception),
    ];
    $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]";
   } else {
    $data = [
     'code' => $this->getCode($exception),
     'message' => $this->getMessage($exception),
    ];
    $log = "[{$data['code']}]{$data['message']}";
   }

   if (Container::get('app')->config('log.record_trace')) {
    $log .= "\r\n" . $exception->getTraceAsString();
   }

   Container::get('log')->record($log, 'error');
   }
  }

  protected function isIgnoreReport(Exception $exception)
  {
   foreach ($this->ignoreReport as $class) {
   if ($exception instanceof $class) {
    return true;
   }
   }

   return false;
  }

  /**
  * Render an exception into an HTTP response.
  *
  * @access public
  * @param \Exception $e
  * @return Response
  */
  public function render(Exception $e)
  {
   if ($this->render && $this->render instanceof \Closure) {
   $result = call_user_func_array($this->render, [$e]);

   if ($result) {
    return $result;
   }
   }

   if ($e instanceof HttpException) {
   return $this->renderHttpException($e);
   } else {
   return $this->convertExceptionToResponse($e);
   }
  }

  /**
  * @access public
  * @param Output $output
  * @param Exception $e
  */
  public function renderForConsole(Output $output, Exception $e)
  {
   if (Container::get('app')->isDebug()) {
   $output->setVerbosity(Output::VERBOSITY_DEBUG);
   }

   $output->renderException($e);
  }

  /**
  * @access protected
  * @param HttpException $e
  * @return Response
  */
  protected function renderHttpException(HttpException $e)
  {
   $status = $e->getStatusCode();
   $template = Container::get('app')->config('http_exception_template');

   if (!Container::get('app')->isDebug() && !empty($template[$status])) {
   return Response::create($e, 'json', $status);
   } else {
   return $this->convertExceptionToResponse($e);
   }
  }

  /**
  * @access protected
  * @param Exception $exception
  * @return Response
  */
  protected function convertExceptionToResponse(Exception $exception)
  {
   // 收集异常数据
   if (Container::get('app')->isDebug()) {
   // 调试模式,获取详细的错误信息
   $data = [
    'name' => get_class($exception),
    'file' => $exception->getFile(),
    'line' => $exception->getLine(),
    'message' => $this->getMessage($exception),
    'trace' => $exception->getTrace(),
    'code' => $this->getCode($exception),
    'source' => $this->getSourceCode($exception),
    'datas' => $this->getExtendData($exception),
    'tables' => [
     'GET Data'    => $_GET,
     'POST Data'    => $_POST,
     'Files'     => $_FILES,
     'Cookies'    => $_COOKIE,
     'Session'    => isset($_SESSION) ? $_SESSION : [],
     'Server/Request Data' => $_SERVER,
     'Environment Variables' => $_ENV,
     'ThinkPHP Constants' => $this->getConst(),
    ],
   ];
   } else {
   // 部署模式仅显示 Code 和 Message
   $data = [
    'code' => $this->getCode($exception),
    'message' => $this->getMessage($exception),
   ];

   if (!Container::get('app')->config('show_error_msg')) {
    // 不显示详细错误信息
    $data['message'] = Container::get('app')->config('error_message');
   }
   }

   //保留一层
   while (ob_get_level() > 1) {
   ob_end_clean();
   }

   $data['echo'] = ob_get_clean();

   $response = Response::create($data, 'json');

   if ($exception instanceof HttpException) {
   $statusCode = $exception->getStatusCode();
   $response->header($exception->getHeaders());
   }

   if (!isset($statusCode)) {
   $statusCode = 500;
   }
   $response->code($statusCode);

   return $response;
  }

  /**
  * 获取错误编码
  * ErrorException则使用错误级别作为错误编码
  * @access protected
  * @param \Exception $exception
  * @return integer    错误编码
  */
  protected function getCode(Exception $exception)
  {
   $code = $exception->getCode();

   if (!$code && $exception instanceof ErrorException) {
   $code = $exception->getSeverity();
   }

   return $code;
  }

  /**
  * 获取错误信息
  * ErrorException则使用错误级别作为错误编码
  * @access protected
  * @param \Exception $exception
  * @return string    错误信息
  */
  protected function getMessage(Exception $exception)
  {
   $message = $exception->getMessage();

   if (PHP_SAPI == 'cli') {
   return $message;
   }

   $lang = Container::get('lang');

   if (strpos($message, ':')) {
   $name = strstr($message, ':', true);
   $message = $lang->has($name) ? $lang->get($name) . strstr($message, ':') : $message;
   } elseif (strpos($message, ',')) {
   $name = strstr($message, ',', true);
   $message = $lang->has($name) ? $lang->get($name) . ':' . substr(strstr($message, ','), 1) : $message;
   } elseif ($lang->has($message)) {
   $message = $lang->get($message);
   }

   return $message;
  }

  /**
  * 获取出错文件内容
  * 获取错误的前9行和后9行
  * @access protected
  * @param \Exception $exception
  * @return array     错误文件内容
  */
  protected function getSourceCode(Exception $exception)
  {
   // 读取前9行和后9行
   $line = $exception->getLine();
   $first = ($line - 9 > 0) ? $line - 9 : 1;

   try {
   $contents = file($exception->getFile());
   $source = [
    'first' => $first,
    'source' => array_slice($contents, $first - 1, 19),
   ];
   } catch (Exception $e) {
   $source = [];
   }

   return $source;
  }

  /**
  * 获取异常扩展信息
  * 用于非调试模式html返回类型显示
  * @access protected
  * @param \Exception $exception
  * @return array     异常类定义的扩展数据
  */
  protected function getExtendData(Exception $exception)
  {
   $data = [];

   if ($exception instanceof \think\Exception) {
   $data = $exception->getData();
   }

   return $data;
  }

  /**
  * 获取常量列表
  * @access private
  * @return array 常量列表
  */
  private static function getConst()
  {
   $const = get_defined_constants(true);

   return isset($const['user']) ? $const['user'] : [];
  }

 }

以上这篇Thinkphp 在api开发中异常返回依然是html的解决方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
如何对PHP程序中的常见漏洞进行攻击(下)
Oct 09 PHP
一个php作的文本留言本的例子(四)
Oct 09 PHP
php adodb连接mssql解决乱码问题
Jun 12 PHP
php 代码优化的42条建议 推荐
Sep 25 PHP
PHP字符串 ==比较运算符的副作用
Oct 21 PHP
php绝对路径与相对路径之间关系的的分析
Mar 03 PHP
一个PHP分页类的代码
May 18 PHP
深入PHP获取随机数字和字母的方法详解
Jun 06 PHP
ThinkPHP的MVC开发机制实例解析
Aug 23 PHP
thinkPHP分组后模板无法加载问题解决方法
Jul 12 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
Nov 17 PHP
php记录搜索引擎爬行记录的实现代码
Mar 02 PHP
PHP 代码简洁之道(小结)
Oct 16 #PHP
解决tp5在nginx下修改配置访问的问题
Oct 16 #PHP
Laravel6.2中用于用户登录的新密码确认流程详解
Oct 16 #PHP
PHP实现15位身份证号转18位的方法分析
Oct 16 #PHP
laravel unique验证、确认密码confirmed验证以及密码修改验证的方法
Oct 16 #PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
Oct 16 #PHP
详解将数据从Laravel传送到vue的四种方式
Oct 16 #PHP
You might like
全国FM电台频率大全 - 4 山西省
2020/03/11 无线电
PHP序列化/对象注入漏洞分析
2016/04/18 PHP
phpcms中的评论样式修改方法
2016/10/21 PHP
解决laravel查询构造器中的别名问题
2019/10/17 PHP
再论Javascript下字符串连接的性能
2011/03/05 Javascript
js 幻灯片的实现
2011/12/06 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
深入探究JavaScript中for循环的效率问题及相关优化
2016/03/13 Javascript
js 获取当前web应用的上下文路径实现方法
2016/08/19 Javascript
利用bootstrapValidator验证UEditor
2016/09/14 Javascript
BootStrap的双日历时间控件使用
2017/07/25 Javascript
JS实现的base64加密解密操作示例
2018/04/18 Javascript
vue和webpack打包项目相对路径修改的方法
2018/06/15 Javascript
vue 避免变量赋值后双向绑定的操作
2020/11/07 Javascript
[03:04]DOTA2超级联赛专访ZSMJ “莫名其妙”的逆袭
2013/05/23 DOTA
Python实现的二维码生成小软件
2014/07/11 Python
python base64 decode incorrect padding错误解决方法
2015/01/08 Python
用Python设计一个经典小游戏
2017/05/15 Python
python的文件操作方法汇总
2017/11/10 Python
修复CentOS7升级Python到3.6版本后yum不能正确使用的解决方法
2018/01/26 Python
Python爬取数据并写入MySQL数据库的实例
2018/06/21 Python
详解Python静态网页爬取获取高清壁纸
2019/04/23 Python
python将print输出的信息保留到日志文件中
2019/09/27 Python
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
英国百安居装饰建材网上超市:B&Q
2016/09/13 全球购物
Pretty You London官网:英国拖鞋和睡衣品牌
2019/05/08 全球购物
2014年社区庆元旦活动方案
2014/03/08 职场文书
2014全国两会心得体会
2014/03/17 职场文书
幼儿园感恩节活动方案
2014/10/06 职场文书
最新农村养殖致富:资金投入较低的创业项目有哪些?
2019/09/26 职场文书
Python中X[:,0]和X[:,1]的用法
2021/05/10 Python
Redis入门教程详解
2021/08/30 Redis
一定要知道的 25 个 Vue 技巧
2021/11/02 Vue.js
海弦WR-800F
2022/04/05 无线电
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
2022/04/14 Python