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+mysql来做一个功能强大的在线计算器
Oct 12 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
Apr 09 PHP
php中通过curl smtp发送邮件
Jun 05 PHP
php仿QQ验证码的实例分析
Jul 01 PHP
浅析十款PHP开发框架的对比
Jul 05 PHP
php使用session二维数组实例
Nov 06 PHP
php判断linux下程序问题实例
Jul 09 PHP
变量在 PHP7 内部的实现(二)
Dec 21 PHP
PHP array_key_exists检查键名或索引是否存在于数组中的实现方法
Jun 13 PHP
phpstudy后门rce批量利用脚本的实现
Dec 12 PHP
Laravel服务容器绑定的几种方法总结
Jun 14 PHP
WordPress伪静态规则设置代码实例
Dec 10 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
PHP XML error parsing SOAP payload on line 1
2010/06/17 PHP
PHP关联链接常用代码
2012/11/05 PHP
PHP面向对象精要总结
2014/11/07 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
Windows下编译PHP5.4和xdebug全记录
2015/04/03 PHP
使用URL传输SESSION信息
2015/07/14 PHP
php操作路径的经典方法(必看篇)
2016/10/04 PHP
PHP实现根据密码长度显示安全条
2017/07/04 PHP
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
超简单JS二级、多级联动的简单实例
2014/02/18 Javascript
js调试系列 初识控制台
2014/06/18 Javascript
基于 Docker 开发 NodeJS 应用
2014/07/30 NodeJs
js鼠标悬浮出现遮罩层的方法
2015/01/28 Javascript
Bootstrap3学习笔记(三)之表格
2016/05/20 Javascript
JS操作JSON方法总结(推荐)
2016/06/14 Javascript
Extjs 点击复选框在表格中增加相关信息行
2016/07/12 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
vuex学习之Actions的用法详解
2017/08/29 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
react实现移动端下拉菜单的示例代码
2020/01/16 Javascript
Python的词法分析与语法分析
2013/05/18 Python
使用python在校内发人人网状态(人人网看状态)
2014/02/19 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Windows中安装使用Virtualenv来创建独立Python环境
2016/05/31 Python
Python while 循环使用的简单实例
2016/06/08 Python
Python基础之函数基本用法与进阶详解
2020/01/02 Python
Pytorch之扩充tensor的操作
2021/03/04 Python
美国知名的时尚购物网站:Anthropologie
2016/12/22 全球购物
Exoticca英国:以最优惠的价格提供豪华异国情调旅行
2018/10/18 全球购物
日本高岛屋百货购物网站:TAKASHIMAYA
2019/03/24 全球购物
学生实习推荐信范文
2013/11/26 职场文书
个性与发展自我评价
2015/03/06 职场文书
HTML中table表格拆分合并(colspan、rowspan)
2021/04/07 HTML / CSS
javascript的var与let,const之间的区别详解
2022/02/18 Javascript