你們知道我最近在給「阿北的知識分享」微信小程序改版,使用的是yii2中的restful功能,接下來把遇到的一些問題及小技巧分享一下。
先安利一下小程序碼 連接javascript
開始分享。php
咱們知道restful風格的url通常是這樣的java
咱們yii2默認的url形式是index.php?r=controller/action。nginx
雖說yii2已經提供了專門針對於restful的路由規則,可是咱們仍是須要服務器支持url重寫把index.php去掉。web
我用的是nginx,以下配置apache
location / { if (!-e $request_filename){ rewrite ^/(.*) /index.php last; } }
若是你的是apache能夠以下配置json
// Apache須要支持url重寫其AllowOverride爲all AllowOverride:all //web目錄下增長.htaccess,隱藏index.php文件 內容以下 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php
或小程序
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)\?*$ index.php/$1 [L,QSA]
默認狀況下yii2的restful已經提供了index、view、update、create和delete共5個action來知足於對資源的不一樣行爲。可能你的接口中不須要delete,有兩個方法微信小程序
url規則中配置(推薦)
好比我不但願開放 DELETE /users/1 則能夠配置對應的url規則以下服務器
[ 'class' => 'yii\rest\UrlRule', 'controller' => 'user', 'except'=>['delete'] ],
重寫action
咱們知道這些內置方法使用了actions方法實現,咱們能夠複寫這個函數。
class UserController extends ActiveController { public $modelClass = 'app\models\User'; public function actions() { $actions = parent::actions(); unset($actions['delete']); return $actions; } ... }
兩種方法均可以實現可是返回結果不相同,感興趣的同窗能夠本身體驗下。
內置方法知足了不少,需求太複雜我想本身在控制器裏增長一個actionAbc的方法,如何配置那?看下面的代碼,仍是在urlManager裏搞定。
[ 'class' => 'yii\rest\UrlRule', 'controller' => 'user', 'except'=>['delete','update','index'], 'extraPatterns'=>[ 'POST abc'=>'abc', ] ],
這樣你就能夠經過 POST /users/abc 來調用User控制器的abc Action了。
我想經過 GET /users 獲取會員的id和nickname字段,很簡單在get參數中傳入fields='id,nickname',這很容易畢竟id和nickname就是user表的列,可是我還想得到每一個會員下的訂單數,而訂單數並不屬於user表,方法以下
增長get參數
咱們須要增長一個叫作expand的參數,值爲你要獲取的字段名字,逗號分隔每個。
GET /users?fields='id,nickname'&expand='oTotal'
配置user模型
咱們須要重寫一個叫作extraFields的方法
public function extraFields() { return [ 'oTotal' ]; }
編寫具體邏輯
接下來咱們要在User模型中編寫實現oTotal的函數
public function getOTotal(){ return Order::find()->where(['user_id'=>$this->id])->count(); }
你發現了什麼?你是否記起了在yii2中一個叫作關聯的概念,你是否發現獲取多種數據變得很簡單了?
使用小程序發起服務器請求,好比新建一本書,咱們通常喜歡編寫以下代碼
wx.request({ method: 'POST', data: { name: name }, url: app.globalData.remoteUrl + '/books', header: { 'content-type': 'application/json' }, success: function (res) { } })
這裏我設置了'content-type': 'application/json',問題發生了,我在服務器端沒法獲取json中的name值。
很簡單,默認狀況下yii2的restful並不支持對請求中json的數據解析,還好小小配置下就能夠了。
// config/web.php 'components' => [ 'request' => [ 'cookieValidationKey' => '', 'parsers' => [ 'application/json' => 'yii\web\JsonParser', ] ], ]
增長一個JsonParser解析器就能夠了。
網頁上有登陸,可是restful上沒有session,不要緊咱們可使用access token來搞定,配置很簡單。
好比我如今要求GET /users 必須是登錄後訪問。
配置user模型和表
首先爲user表配置一個access_token字段,同時在User模型下作一個generateAccessToken方法
public function generateAccessToken(){ $this->access_token = Yii::$app->security->generateRandomString(); }
該方法主要用於生成access_token值。
固然咱們的User模型須要實現 yiiwebIdentityInterface 接口,不然使用Yii::$app->user沒法訪問的,關於IdentityInterface我想在yii2登陸這裏已經很熟悉了,記住restful的認證若是生效還要實現以下方法
public static function findIdentityByAccessToken($token, $type = null) { $model = User::find()->where(['access_token'=>$token])->one(); return $model; }
到這裏User模型就配置好了,小提醒:若是你想作一些登陸那一刻的事兒,能夠也放到findIdentityByAccessToken,好比記錄登陸時間啥的。
配置action
接下來咱們來對具體的接口進行認證限制,複寫behaviors行爲,以下
use yii\filters\auth\HttpBearerAuth; class UserController extends ActiveController { public $modelClass = "app\models\User"; public function behaviors() { $behaviors = parent::behaviors(); $behaviors['contentNegotiator']['formats'] = ['application/json'=>Response::FORMAT_JSON]; $behaviors['authenticator'] = [ 'class'=>HttpBearerAuth::className(), 'only'=>[ 'index' ], ]; return $behaviors; } }
這樣就搞定了,咱們這裏用的是HttpBearerAuth認證,就是在請求的header裏面寫Authorization,yii2的restful還支持其餘的。記住這個認證過程是自動的,而且咱們在認證的方法裏可使用Yii::$app->user->id獲取當前會員的ID。
咱們知道經過 GET /users 能夠得到會員列表,可是你可能說我要獲取來自於微信平臺的會員(user表裏有一個字段plat表明來源平臺),怎麼辦?
咱們須要從新編寫該接口並接受plat參數,在User控制器中先設置新的prepareDataProvider函數,它用來接收參數並生成會員列表數據,返回的是一個ActiveDataProvider結果集。
namespace app\modules\xcx\controllers; use Yii; use yii\rest\ActiveController; .... class UserController extends ActiveController { public $modelClass = 'app\models\User'; public function actions() { $actions = parent::actions(); $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider']; return $actions; } public function prepareDataProvider(){ $params = Yii::$app->request->queryParams; $modelClass = $this->modelClass; $query = $modelClass::find()->where(['plat'=>$params['plat']]); $provider = new ActiveDataProvider([ 'query'=>$query->orderBy(['created_at'=>SORT_DESC]) ]); return $provider; } }
首先經過 $actions['index']['prepareDataProvider'] = [$this,'prepareDataProvider'] 告訴yii2我要自定義獲取結果集的方法,接下來定義這個方法,在prepareDataProvider裏能夠經過Yii::$app->request->queryParams 接收過來的get參數的值。
以上就是目前爲止在使用yii2的restful開發小程序時候使用的一些知識和技巧,但願對你有用,之後若是有再分享哈。