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生成HTML静态页面实例代码
Aug 31 PHP
使用eAccelerator加密PHP程序
Oct 03 PHP
php 清除网页病毒的方法
Dec 05 PHP
用php随机生成福彩双色球号码的2种方法
Feb 04 PHP
解析PHP高效率写法(详解原因)
Jun 20 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
Aug 22 PHP
php+MySQL判断update语句是否执行成功的方法
Aug 28 PHP
ThinkPHP写数组插入与获取最新插入数据ID实例
Nov 03 PHP
php生成excel列名超过26列大于Z时的解决方法
Dec 29 PHP
PHP 实现代码复用的一个方法 traits新特性
Feb 22 PHP
深入浅析PHP7.0新特征(五大新特征)
Oct 29 PHP
laravel 查询数据库获取结果实现判断是否为空
Oct 24 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共享内存段示例分享
2014/01/20 PHP
PHP基于openssl实现的非对称加密操作示例
2019/01/11 PHP
让iframe框架网页在任何浏览器下自动伸缩
2006/08/18 Javascript
javascript编程起步(第五课)
2007/02/27 Javascript
javascript中自定义对象的属性方法分享
2013/07/12 Javascript
Javascript基础教程之数据类型 (布尔型 Boolean)
2015/01/18 Javascript
JQuery实现网页右侧随动广告特效
2016/01/17 Javascript
dul无法加载bootstrap实现unload table/user恢复
2016/09/29 Javascript
利用Javascript实现一套自定义事件机制
2017/12/14 Javascript
详解vue中axios的封装
2018/07/18 Javascript
获取layer.open弹出层的返回值方法
2018/08/20 Javascript
layer.js之回调销毁对话框的例子
2019/09/11 Javascript
angular inputNumber指令输入框只能输入数字的实现
2019/12/03 Javascript
python实现的文件夹清理程序分享
2014/11/22 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
2019/08/02 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
2020/01/04 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
推荐10个CSS3 制作的创意下拉菜单效果
2014/02/11 HTML / CSS
来自美国主售篮球鞋的零售商店:KICKSUSA
2017/11/28 全球购物
天猫国际进口超市直营:官方直采,一站购齐
2017/12/11 全球购物
Linux的文件类型
2016/07/05 面试题
学生会主席就职演讲稿
2014/01/14 职场文书
班级聚会策划书
2014/01/16 职场文书
经济信息系毕业生自荐信范文
2014/03/15 职场文书
公务员保密承诺书
2014/03/27 职场文书
入党推优材料
2014/06/02 职场文书
自主招生学校推荐信
2014/09/26 职场文书
市委常委会班子党的群众路线教育实践活动整改方案
2014/10/25 职场文书
食品质检员岗位职责
2015/04/08 职场文书
2015年幼儿教师个人工作总结
2015/05/20 职场文书
师范生教育见习总结
2015/06/23 职场文书
环保守法证明
2015/06/24 职场文书
2016七夕情人节广告语
2016/01/28 职场文书
nginx刷新页面出现404解决方案(亲测有效)
2022/03/18 Servers
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server
springboot读取resources下文件的方式详解
2022/06/21 Java/Android