提示
本教程相关代码托管在Gitee:gitee.com/toshcn/micr…
配置公共组件
打开common/config/main.php文件,配置公共组件:
<?php
// 在公共配置添加组件项
return [
'components' => [
...
// 配置常用工具类组件utils
'utils' => [
'class' => 'common\components\Utils'
]
]
];
配置api项目公共组件
打开api/config/main.php文件,配置公共组件:
<?php
// 在api项目公共配置添加组件项
return [
'components' => [
...
// 配置接口数据统一返回格式类组件api
'api' => [
'class' => 'common\components\ApiResponse'
]
]
];
创建语言翻译文本
在项目common/language目录下创建目录zh-CN,在zh-CN目录创建common.php文件,文件内容如下:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
/**
* 中文翻译文本
* 使用方法:\Yii::t('common', 数组键名)
*/
return [
'Please login first.' => '请先登录',
'The Authorization is invalid.' => '访问令牌无效',
];
创建Utils组件类
在项目common\components根目录下,创建Utils.php文件,文件添加如下内容:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace common\components;
use yii\base\BaseObject;
/**
* 公共的常用工具类组件 调用方式 \Yii::$app->utils->方法名()
* Class Utils
* @package common\components
*/
class Utils extends BaseObject
{
/** @var string 缓存统一key前缀 */
public static $cacheKeyPrefix = '__utils:';
/**
* 生成统一的缓存键名
* @param string $key 缓存key
* @return string
*/
public static function cacheKey($key = '')
{
return static::$cacheKeyPrefix . md5(__DIR__) . $key;
}
}
创建ApiResponse接口数据格式统一返回组件
在项目api\conponents目录下,创建ApiResponse.php文件,文件添加如下内容:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace common\components;
use yii\base\BaseObject;
/**
* Api 接口数据统一返回格式
* @package api\components
*/
class ApiResponse extends BaseObject
{
const ERROR = 0; // 请求错误
const SUCCESS = 1; // 请求成功
/**
* @var int 错误码
* 错误码建议用下面规则
* 0 接口错误 1 接口成功 >1为详细错误
* 权限错误: 1000-1999
* 资源错误: 3000-3999
* 请求参数错误: 4000-4999
* 服务器错误: 5000-5999
*/
private $_errCode = 0;
/**
* @var string 错误码对应提示说明.
*/
private $_message = 'success';
/**
* 状态码及其对应描述文本
* @var array
*/
private $_apiStatusesMessage = [
0 => 'error',
1 => 'success'
];
/**
* 设置Api 错误码
* @param int $value 错误码
* @param string $text 错误码描述文本
*/
public function setErrCode($value, $text = null)
{
$this->_errCode = (int) $value;
if ($text === null) {
$this->_message = !empty($this->_apiStatusesMessage[$this->_errCode])
? $this->_apiStatusesMessage[$this->_errCode]
: '';
} else {
$this->_message = $text;
}
}
/**
* 接口请求成功
*
* @param array $data 要返回的数据内容
* @param string $text 状态码描述文本
* @return array
*/
public function success($data = [], $text = null)
{
$this->setErrCode(static::SUCCESS, $text);
return [
'status' => static::SUCCESS,
'code' => static::SUCCESS,
'message' => $this->_message,
'data' => $data,
];
}
/**
* 接口请求错误
*
* @param int $code 错误码
* @param array $data 要返回的数据内容
* @param string $text 错误码描述文本
* @return array
*/
public function error($code, $text = null, $data = [])
{
$this->setErrCode($code, $text);
return [
'status' => static::ERROR,
'code' => $this->_errCode,
'message' => $this->_message,
'data' => $data
];
}
}
创建ApiController接口公共基类控制器
在项目api\controllers目录下,创建ApiController.php文件,文件添加如下内容:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace api\controllers;
use yii\rest\Controller;
use yii\filters\Cors;
use yii\helpers\ArrayHelper;
/**
* API 项目基类控制器 api项目所有接口控制器都要继承此类
* Class ApiController
* @package api\controllers
*/
class ApiController extends Controller
{
/**
* 配置控制器行为
* @return array
*/
public function behaviors()
{
$behaviors = ArrayHelper::merge([
'corsFilter' => [
'class' => Cors::class,
'cors' => [
'Origin' => ['*'], // 跨域配置 *允许全部域名
// 可过滤请求的动作类型 如: 可配置只允许POST和GET
'Access-Control-Request-Methods' => ['POST', 'PUT', 'GET', 'OPTIONS'],
'Access-Control-Request-Headers' => ['*']
]
]
], parent::behaviors());
// 是否在HTTP头带上目前的速率限制信息
$behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
return $behaviors;
}
/**
* 重载请求动作方法前
* 可在此处做一些代码检查,比如网站是否关闭,用户是否登录
* @param mixed $action 当前请求的动作
* @return bool
* @throws \yii\web\BadRequestHttpException
*/
public function beforeAction($action)
{
$res = parent::beforeAction($action);
// 检测网站是否关闭
// todo
return $res;
}
}
创建AuthController认证接口公共基类控制器
在项目api\controllers目录下,创建AuthController.php文件,文件添加如下内容:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace api\controllers;
use Yii;
use yii\filters\auth\HttpBearerAuth;
/**
* API项目认证类控制器 api项目需要用户登录的接口的控制器都要继承此类
* Class AuthController
* @package api\controllers
*/
class AuthController extends ApiController
{
// 错误码 令牌无效
const ERR_CODE_AUTHORIZATION_INVALID = 3002;
// 错误码 未登录
const ERR_CODE_NOT_LOGGED_IN = 3001;
/**
* 在请求动作前检测会员登录状态
* @param mixed $action 当前请求的动作
* @return bool
* @throws \yii\web\BadRequestHttpException
*/
public function beforeAction($action)
{
$res = parent::beforeAction($action);
// 检测会员登录状态 如果用户未登录 取出请求标头 使用标头保存的token登录用户账号
if ($res && Yii::$app->getUser()->isGuest) {
$auth = new HttpBearerAuth();
// 获取PHP请求标头:Authorization
$authHeader = Yii::$app->getRequest()->getHeaders()->get($auth->header);
if ($auth->pattern !== null) {
// 用正则取出标头 保存在变量$matches中,$matches下标1为token的值
if (preg_match($auth->pattern, $authHeader, $matches)) {
$authHeader = empty($matches[1]) ? false : $matches[1];
// 如果Authorization标头不为空,尝试用token登录用户账号
if ($authHeader && Yii::$app->getUser()->loginByAccessToken($authHeader, get_class($auth))) {
// 登录成功
return true;
}
// 登录令牌无效
Yii::$app->getResponse()->data = Yii::$app->api->error(
static::ERR_CODE_AUTHORIZATION_INVALID,
Yii::t('common', 'The Authorization is invalid.')
);
Yii::$app->getResponse()->send();
return false;
}
}
// 未登录
Yii::$app->getResponse()->data = Yii::$app->api->error(
static::ERR_CODE_NOT_LOGGED_IN,
Yii::t('common', 'Please login first.')
);
Yii::$app->getResponse()->send();
}
// 禁止未登录访问接口
return false;
}
}
修改TestController控制器
在项目api\controllers目录下,修改TestController.php文件,文件修改如下:
<?php
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/14 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace api\controllers;
/**
* 测试控制器类
* Class TestController
* @package api\controllers
*/
class TestController extends AuthController
{
/**
* 测试动作
* @return array
*/
public function actionIndex()
{
return \Yii::$app->api->error();
}
}
修改User模型命令空间
打开common/models/User.php文件,修改如下:
...
namespace common\modules; // 原内容
namespace common\models; // 修改为
...
访问test控制器
打开浏览器,在地址栏输入www.mysite.local/test/index mysite.local 替换为实际的主机名,将会看到输出xml如下内容:
<?xml version="1.0" encoding="utf-8"?>
<response>
<status>0</status>
<code>3001</code>
<message>请先登录</message>
<data/>
</response>
用Postman模拟请求,设置请求标头content-type为application/json; charset=UTF-8,
设置请求标头Authorization 为空,将会看到如下内容:
{
"status": 0,
"code": 3002,
"message": "令牌无效",
"data": []
}
修改语言配置
打开common/config/main.php文件,修改如下:
...
//'language' => 'zh-CN', // 设置目标语言 注释语言配置,或配置为en-US
...
再次访问test控制器,你将看到接口返回的message为英文。
OK现在创建User接口控制器
打开api/modules/v1/controllers目录,创建UserController.php文件,文件内容如下:
<?php /** @noinspection ALL */
/**
* @link https://gitee.com/toshcn/micro-hau
* @copyright Copyright (c) 2022/4/20 micro-hau
* @author toshcn <toshcn@foxmail.com>
*/
namespace api\modules\v1\controllers;
use api\controllers\ApiController;
/**
* 用户接口控制器
* Class UserController
* @package api\modules\v1\controllers
*/
class UserController extends ApiController
{
/**
* @return mixed
*/
public function actionIndex()
{
return \Yii::$app->api->success(['id' => 1, 'nickname' => '测试用户']);
}
}
访问user控制器
打开浏览器,在地址栏输入www.mysite.local/v1/user/ind… mysite.local 替换为实际的主机名,将会看到输出xml如下内容:
<?xml version="1.0" encoding="utf-8"?>
<response>
<status>1</status>
<code>1</code>
<message>success</message>
<data>
<id>1</id>
<nickname>测试用户</nickname>
</data>
</response>
用Postman模拟请求,设置请求标头content-type为application/json; charset=UTF-8,将会看到如下内容:
{
"status": 1,
"code": 1,
"message": "success",
"data": {
"id": 0,
"nickname": "测试用户"
}
}