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类
Jul 15 PHP
PHP中的串行化变量和序列化对象
Sep 05 PHP
php递归创建和删除文件夹的代码小结
Apr 13 PHP
php Calender(日历)代码分享
Jan 03 PHP
php判断文件上传类型及过滤不安全数据的方法
Dec 17 PHP
Php-Redis安装测试笔记
Mar 05 PHP
整理php防注入和XSS攻击通用过滤
Sep 13 PHP
PHP遍历目录文件的常用方法小结
Feb 03 PHP
PHP使用Redis长连接的方法详解
Feb 12 PHP
PHP实现字符串的全排列详解
Apr 24 PHP
ThinkPHP 5.1 跨域配置方法
Oct 11 PHP
php中yii框架实例用法
Dec 22 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
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
PHP模板引擎Smarty之配置文件在模板变量中的使用方法示例
2016/04/11 PHP
jquery中输入验证中一个不错的效果
2010/08/21 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
js 实现菜单上下显示附效果图
2013/11/21 Javascript
JS替换字符串中字符即替换全部而不是第一个
2014/06/04 Javascript
删除javascript中注释语句的正则表达式
2014/06/11 Javascript
node.js中的fs.symlink方法使用说明
2014/12/15 Javascript
jQuery选择器源码解读(八):addCombinator函数
2015/03/31 Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
2015/11/17 Javascript
jquery实现垂直和水平菜单导航栏
2020/08/27 Javascript
jQuery插件HighCharts绘制简单2D折线图效果示例【附demo源码】
2017/03/21 jQuery
JavaScript算法教程之sku(库存量单位)详解
2017/06/29 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
Angularjs 根据一个select的值去设置另一个select的值方法
2018/08/13 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
Vue.js获取被选择的option的value和text值方法
2018/08/24 Javascript
详解微信小程序的不同函数调用的几种方法
2019/05/08 Javascript
jQuery实现日历效果
2020/09/11 jQuery
Python多继承以及MRO顺序的使用
2019/11/11 Python
Python求解排列中的逆序数个数实例
2020/05/03 Python
python读取图像矩阵文件并转换为向量实例
2020/06/18 Python
python导入库的具体方法
2020/06/18 Python
canvas实现圆绘制的示例代码
2019/09/11 HTML / CSS
介绍下Lucene建立索引的过程
2016/03/02 面试题
毕业自我鉴定范文
2013/11/06 职场文书
电子商务专业个人的自我评价
2013/11/19 职场文书
茶叶店创业计划书范文
2014/01/19 职场文书
医药营销个人求职信范文
2014/02/07 职场文书
入职担保书范文
2014/05/21 职场文书
2014年单位工作总结范文
2014/11/27 职场文书
2014年纠风工作总结
2014/12/08 职场文书
消夏晚会主持词
2015/06/30 职场文书
python 实现定时任务的四种方式
2021/04/01 Python
微前端qiankun改造日渐庞大的项目教程
2022/06/21 Javascript
Navicat Premium自定义 sql 标签的创建方式
2022/09/23 数据库