部署
1.安装TP6稳定版
composer create-project topthink/think api_service
2.URL重写
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
3.安装多应用模式扩展think-multi-app
composer require topthink/think-multi-app
4.创建应用
php think build api
5.配置路由
修改路由配置 开启强制路由模式 config/route.php
// 是否强制使用路由
'url_route_must' => true,
6.API版本控制
controller目录新建文件夹v1 创建控制器 Index.php
<?php
namespace app\api\controller\v1;
class Index
{
public function index()
{
return 'ok';
}
}
创建路由测试,将根目录的route目录复制一份到api目录,编辑app.php
<?php
use think\facade\Route;
// 测试
Route::rule(':version/index', ':version.Index/index');
访问 http://127.0.0.1:81/api/v1/index
API统一返回格式
在应用目录新建目录common,将app目录下的BaseController.php移动到common目录,修改命名空间,删除不需要的代码片段,所有控制器都继承这个文件。
<?php
namespace app\api\common;
use think\App;
/**
* 控制器基础类
* @package app\api\common
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
}
}
封装两个公共静态方法方便调用:showResCode,showResCodeWithOutData,分别用于有数据和无数据返回时的使用场景。
/**
* API统一数据返回
* @param string $msg 提示信息
* @param array $data 数据包
* @param string $type 数据类型 json
* @param array $header 设置响应头
* @param int $code HTTP状态码 200
* @return Response
*/
public static function showResCode($msg = '请求成功', $data = [], $type = 'json', $header = [], $code = 200)
{
$data = [
'msg' => $msg,
'data' => $data
];
return Response::create($data, $type, $code)->header($header);
}
/**
* API统一无数据返回
* @param string $msg 提示信息
* @param string $type 数据类型 json
* @param array $header 设置响应头
* @param int $code HTTP状态码 200
* @return Response
*/
public static function showResCodeWithOutData($msg = '请求成功', $type = 'json', $header = [], $code = 200)
{
return self::showResCode($msg, [], $type, $header, $code);
}
return self::showResCode('数据列表', [
'total' => 1,
'pageNo' => 1,
'pageNum' => 15,
'list' => [
'id' => 1,
'name' => '张三'
]
]);
return self::showResCodeWithOutData('提交成功');
API统一管理业务状态码
在config配置目录新建文件status_code.php,这里我使用的是常量的方式,在编辑器中可以关键词联想比较方便。
<?php
/**
* 业务状态码
* 业务状态码 统一 ERR开头
* HTTP状态码 统一 HTTP开头
*/
// 异常默认状态码
const ERR_DEFAULT = 999;
// 业务异常默认HTTP状态码
const HTTP_ERR_DEFAULT = 400;
// 框架内部异常状态码
const HTTP_ERR_FRAMEWORK = 500;
API异常错误处理
TP6官方文档异常处理 www.kancloud.cn/manual/thin…
默认安装应用后,TP6已经内置了一个
app\ExceptionHandle异常处理类,直接修改该类的相关方法即可完成应用的自定义异常处理机制。
在common目录创建BaseException.php
<?php
namespace app\api\common;
class BaseException extends \Exception
{
/**
* @var int 默认状态码
*/
public $code = HTTP_ERR_DEFAULT;
/**
* @var string 错误信息
*/
public $msg = '接口异常';
/**
* @var int 错误状态码
*/
public $errorCode = ERR_DEFAULT;
/**
* BaseException constructor.
* @param array $params
*/
public function __construct(array $params = [])
{
if (array_key_exists('code', $params)) $this->code = $params['code'];
if (array_key_exists('msg', $params)) $this->msg = $params['msg'];
if (array_key_exists('errorCode', $params)) $this->errorCode = $params['errorCode'];
}
}
封装API异常输出函数放入应用公共文件,用于手动抛出API异常,在框架异常处理类做出相应的捕获处理
<?php
// 应用公共文件
use app\api\common\BaseException;
/**
* API异常输出
* @param string $msg 错误信息
* @param int $errorCode 错误代码
* @param int $code 状态码
* @throws BaseException
*/
function ApiException($msg = '接口异常', $errorCode = 999, $code = 400)
{
throw new BaseException([
'code' => $code,
'msg' => $msg,
'errorCode' => $errorCode
]);
}
修改框架内置异常错误处理类app\ExceptionHandle的render方法
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
框架自带的错误处理对API来说并不友好,在正常情况下API的返回应该统一格式,所以这里我将异常错误信息统一输出为JSON格式,在本地调试模式下显示框架原本的错误显示,方便查看和定位错误。
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
if ($e instanceof BaseException) {
$this->code = $e->code;
$this->msg = $e->msg;
$this->errorCode = $e->errorCode;
} else {
//调试模式下 输出框架默认错误提示
if (env('APP_DEBUG')) return parent::render($request, $e);
$this->code = HTTP_ERR_FRAMEWORK;
$this->msg = $e->getMessage();
$this->errorCode = ERR_DEFAULT;
}
return json([
'msg' => $this->msg,
'errorCode' => $this->errorCode
], $this->code);
}
手动抛出API异常
新增业务状态码 ERR_NOT_LOGIN
// 未登录
const ERR_NOT_LOGIN = 1001;
ApiException('您还没有登录,请先登录', ERR_NOT_LOGIN);
系统异常捕获处理
在本地开启调试模式下,将显示框架原有的html页面
待续...