Yii2 基於RESTful架構的 advanced版API接口開發 配置、實現、測試,yii2restful
環境配置:
開啟服務器偽靜態
本處以apache為例,查看apache的conf目錄下httpd.conf,找到下面的代碼
LoadModule rewrite_module modules/mod_rewrite.so
將其前面的#去掉,如果沒有找到則添加進去。
找到一下代碼
<Directory "C:/phpStudy/Apache/cgi-bin">
AllowOverride All
Options None
Require all granted
</Directory>
將原本的AllowOverride None改為AllowOverride All。
然後在站點根目錄下創建一個.htaccess文件,內容如下:

![]()
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php
</IfModule>
.htaccess
此處不再贅述yii2的配置,如果需要可以看YII2實戰手冊。
YII2實際操作:
1、配置URL規則及modules

(1)新建modules文件夾,實行api接口版本控制。例如V1版本、V2版本……
在v1文件夾下新建controllers文件夾(控制器)、models文件夾(模型)、Module.php配置文件。
Module.php文件如下:
1 <?php
2 namespace api\modules\v1;
3
4 class Module extends \yii\base\Module
5 {
6
7 public $controllerNamespace = 'api\modules\v1\controllers';
8
9 public function init()
10 {
11 parent::init();
12 }
13 }
第2行和第7行隨版本擴展而變化(v1->v2...)。
(2)配置config文件夾下的main.php文件

![]()
1 <?php
2 $params = array_merge(require (__DIR__ . '/../../common/config/params.php'), require (__DIR__ . '/../../common/config/params-local.php'), require (__DIR__ . '/params.php'), require (__DIR__ . '/params-local.php'));
3
4 return [
5 'id' => 'app-api',
6 'basePath' => dirname(__DIR__),
7 'bootstrap' => [
8 'log'
9 ],
10 'modules' => [
11 'v1' => [
12 'class' => 'api\modules\v1\Module'
13 ],
14 'v2' => [
15 'class' => 'api\modules\v2\Module'
16 ]
17 ],
18 'controllerNamespace' => 'api\controllers',
19 'components' => [
20 'user' => [
21 'identityClass' => 'common\models\User',
22 'enableAutoLogin' => false,
23 'enableSession' => false,
24 'loginUrl' => null
25 ],
26 'urlManager' => [
27 'enablePrettyUrl' => true, // 啟用美化URL
28 'enableStrictParsing' => true, // 是否執行嚴格的url解析
29 'showScriptName' => false, // 在URL路徑中是否顯示腳本入口文件
30 'rules' => [
31 [
32 'class' => 'yii\rest\UrlRule',
33 'controller' => [
34 'v1/site'
35 ]
36 ],
37 [
38 'class' => 'yii\rest\UrlRule',
39 'controller' => [
40 'v2/site'
41 ]
42 ]
43 ]
44 ],
45 'log' => [
46 'traceLevel' => YII_DEBUG ? 3 : 0,
47 'targets' => [
48 [
49 'class' => 'yii\log\FileTarget',
50 'levels' => [
51 'error',
52 'warning'
53 ]
54 ]
55 ]
56 ],
57 'errorHandler' => [
58 'errorAction' => 'site/error'
59 ]
60 ],
61 'params' => $params
62 ];
main.php
注意10~17行、20~44行的組件配置,相信大家仔細閱讀就能明白,此處不再贅述原理,請大家尤其注意33~35行的代碼,此處表示的是v1/site控制器,隨著接口控制器的增多,可以直接在數組中增加即可。本文力求快速配置出RESTful架構的實現。
(3)v2、v3表示以後的版本變化,配置都類似於v1文件夾。
2、創建一個模型
數據庫准備一個名為mxq_guide的數據表
CREATE TABLE `mxq_guide` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`imgurl` varchar(255) DEFAULT NULL COMMENT '圖片路徑',
`status` int(11) DEFAULTNULL COMMENT '1啟用 0禁用',
`flag` int(11) DEFAULTNULL COMMENT '1安卓 2蘋果',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT='APP導航圖';
創建後請注意及時往數據庫添加幾條數據信息。
通過腳手架gii來創建guide.php模型(使用方法請看yii2權威指南)。生成後的文件注意改寫,修改為如下形式以滿足RESTful的需求。之後從models文件夾中轉移到v1/models文件夾中,並注意命名空間的修改。

![]()
1 <?php
2 namespace api\modules\v1\models;
3
4 use Yii;
5 use yii\db\ActiveRecord;
6 use yii\web\IdentityInterface;
7
8 /**
9 * This is the model class for table "{{%guide}}".
10 *
11 * @property integer $id
12 * @property string $imgurl
13 * @property integer $status
14 * @property integer $flag
15 */
16 class Guide extends ActiveRecord implements IdentityInterface
17 {
18
19 public static function findIdentityByAccessToken($token, $type = null)
20 {
21 return static::findOne([
22 'access_token' => $token
23 ]);
24 }
25
26 public function getId()
27 {
28 return $this->id;
29 }
30
31 public function getAuthKey()
32 {
33 return $this->authKey;
34 }
35
36 public function validateAuthKey($authKey)
37 {
38 return $this->authKey === $authKey;
39 }
40
41 public static function findIdentity($id)
42 {
43 return static::findOne($id);
44 }
45
46 public static function tableName()
47 {
48 return '{{%guide}}';
49 }
50
51 public function rules()
52 {
53 return [
54 [
55 [
56 'imgurl',
57 'status',
58 'flag'
59 ],
60 'required'
61 ],
62 [
63 [
64 'status',
65 'flag'
66 ],
67 'integer'
68 ],
69 [
70 [
71 'imgurl'
72 ],
73 'string',
74 'max' => 255
75 ]
76 ];
77 }
78
79 public function attributeLabels()
80 {
81 return [
82 'id' => Yii::t('app', 'ID'),
83 'imgurl' => Yii::t('app', 'imgurl'),
84 'status' => Yii::t('app', 'status'),
85 'flag' => Yii::t('app', 'flag')
86 ];
87 }
88 }
guide.php
3、創建一個控制器

![]()
1 <?php
2 namespace api\modules\v1\controllers;
3
4 use Yii;
5 use yii\rest\ActiveController;
6 use yii\filters\auth\CompositeAuth;
7 use yii\filters\auth\QueryParamAuth;
8 use yii\data\ActiveDataProvider;
9
10 class SiteController extends ActiveController
11 {
12
13 public $modelClass = 'api\modules\v1\models\guide';
14
15 public $serializer = [
16 'class' => 'yii\rest\Serializer',
17 'collectionEnvelope' => 'items'
18 ];
19
20 // public function behaviors()
21 // {
22 // $behaviors = parent::behaviors();
23 // $behaviors['authenticator'] = [
24 // 'class' => CompositeAuth::className(),
25 // 'authMethods' => [
26 // QueryParamAuth::className()
27 // ]
28 // ];
29 // return $behaviors;
30 // }
31 public function actions()
32 {
33 $actions = parent::actions();
34 // 注銷系統自帶的實現方法
35 unset($actions['index'], $actions['update'], $actions['create'], $actions['delete'], $actions['view']);
36 return $actions;
37 }
38
39 public function actionIndex()
40 {
41 $modelClass = $this->modelClass;
42 $query = $modelClass::find();
43 return new ActiveDataProvider([
44 'query' => $query
45 ]);
46 }
47
48 public function actionCreate()
49 {
50 $model = new $this->modelClass();
51 // $model->load(Yii::$app->getRequest()
52 // ->getBodyParams(), '');
53 $model->attributes = Yii::$app->request->post();
54 if (! $model->save()) {
55 return array_values($model->getFirstErrors())[0];
56 }
57 return $model;
58 }
59
60 public function actionUpdate($id)
61 {
62 $model = $this->findModel($id);
63 $model->attributes = Yii::$app->request->post();
64 if (! $model->save()) {
65 return array_values($model->getFirstErrors())[0];
66 }
67 return $model;
68 }
69
70 public function actionDelete($id)
71 {
72 return $this->findModel($id)->delete();
73 }
74
75 public function actionView($id)
76 {
77 return $this->findModel($id);
78 }
79
80 protected function findModel($id)
81 {
82 $modelClass = $this->modelClass;
83 if (($model = $modelClass::findOne($id)) !== null) {
84 return $model;
85 } else {
86 throw new NotFoundHttpException('The requested page does not exist.');
87 }
88 }
89
90 public function checkAccess($action, $model = null, $params = [])
91 {
92 // 檢查用戶能否訪問 $action 和 $model
93 // 訪問被拒絕應拋出ForbiddenHttpException
94 // var_dump($params);exit;
95 }
96 }
SiteController.php
控制器請創建在modules/controllers文件夾下,並注意命名空間的修改。
要注意的是,此處的控制器與普通的控制器繼承Controller不同,此處需繼承ActiveController類。
20~30行注釋的代碼是基於RESTful架構的access_token認證,目前還未測試通過,後續補充。
至此,基於YII2的所有配置已基本完成,接下來介紹api接口測試工具及方法。
RESTful的測試工具PostMAN:
首先介紹一下postman這款插件,是基於谷歌浏覽器的一款模擬請求的實用插件。具體使用,在下面測試過程中涉及截圖,介紹不足之處請見諒,自己也是第一次使用。

推薦使用上面的APP版本,便於後續封裝自己寫好的api接口,下面的是網頁版本。
YII2支持的RESTful有四種請求方式:GET查看信息,POST創建信息,PUT更新信息,DELETE刪除信息。
下面開始演示四種請求數據的方式。(只是截圖演示效果,具體使用還需要大家自己去摸索。)

此處演示的是GET方法請求數據庫的數據。對應的是modules/controllers/SiteController/actionIndex方法。
請大家注意最上面方框內的URL地址,rest默認將控制器進行復數請求http://api.mxq.com/v1/sites,此處就是rest的默認規則。
打*星號位置顯示的是正常的效果,如若出現錯誤,大家可以去YII權威指南——錯誤檢查錯誤原因。
YII2的ActiveController默認實現了數據的分頁效果。

此處演示的是POST方法新建數據庫的數據。對應的是modules/controllers/SiteController/actionCreate方法。
如果在數據庫的數據層寫好數據校驗規則,此處提交數據不滿足要求的時候就會顯示相應的錯誤。這也是REST的優勢之一。比如如下情況,flag我定義的是int型:

接下來演示的是PUT方法更新數據庫的數據。對應的是modules/controllers/SiteController/actionUpdate方法。

此處請大家再次注意最上面的URL:http://api.mxq.com/v1/sites/15 此處15代表的是數據庫id為15的數據,表示更新數據庫ID為15的數據信息。請大家一定注意。RESTful在使用更新和刪除數據操作的時候,id不能一表單的形式提交,必須緊跟在URL之後。
接下來演示的是DELETE方法刪除數據庫的數據。對應的是modules/controllers/SiteController/actionDelete方法。

當返回值為1的時候表示的就是刪除操作執行成功。具體原理請大家仔細觀察sitecontroller控制器內的函數。
以上就是基於yii2的RESTful的一些簡單介紹、實現方法以及測試結果。有什麼不正確或遺漏的地方,歡迎大家來補充。後續也會在此基礎上進行更新。本人第一次接觸yii2框架和RESTful架構,表述如有不對之處,請大家見諒。