這篇說下yii2.0
開發 API
吧,使用 RESTful
API模式
透過 Composer 安裝
這是安裝Yii2.0的首選方法。如果你還沒有安裝 Composer
,你可以按照這裡的說明進行安裝。
安裝完 Composer
,執行下面的命令來安裝 Composer Asset
外掛:
php composer.phar global require "fxp/composer-asset-plugin:^1.2.0"
安裝高階的應用程式模板,執行下面的命令:
php composer.phar create-project yiisoft/yii2-app-advanced advanced 2.0.13
初始化高階模板
cd advanced
init
修改資料庫連線屬性
開啟 common\config\main-local.php
,配置資料庫連線資訊
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=yiiapi',
'username' => 'root',
'password' => 'root',
'charset' => 'utf8',
],
執行 migrate
資料庫遷移
yii migrate
複製backend目錄,命名為api
開啟api\config\main.php
修改id
,controllerNamespace
:
return [
'id' => 'app-api',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'api\controllers',
]
開啟common\config\main.php
開啟url
路由美化規則
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
開啟common\config\bootstrap.php
新增以下別名
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api');
配置 Web 伺服器
很多同學在看了我這個教程,說是執行不起來、一直是404,然後就問我為什麼?我看了好多,他們都是本地使用 Apache
,並且 index.php
檔案沒有隱藏,他們訪問地址也不叫 index.php
。所以在此說明一下吧
Apache 配置
# 設定文件根目錄為 "path/to/api/web"
DocumentRoot "path/to/api/web"
<Directory "path/to/api/web">
# 開啟 mod_rewrite 用於美化 URL 功能的支援(譯註:對應 pretty URL 選項)
RewriteEngine on
# 如果請求的是真實存在的檔案或目錄,直接訪問
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 如果請求的不是真實檔案或目錄,分發請求至 index.php
RewriteRule . index.php
# if $showScriptName is false in UrlManager, do not allow accessing URLs with script name
RewriteRule ^index.php/ - [L,R=404]
# ...其它設定...
</Directory>
或者 在web 目錄下新建一個 .htaccess
檔案,填入以下內容(我這是從 Laravel 專案中複製過來的),同樣可以起到隱藏 index.php
的效果
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Nginx 的配置
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
為什麼要單獨建立API應用
單獨建立API應用,目的是便於維護,可以避免以下問題
- 配置的衝突
- 控制器的命名不便
- url美化規則衝突
- 分工明確
frontend
為前臺目錄;backend
為後臺目錄;api
為api目錄
接下來開啟 api\controllers
新建一個User控制器,繼承 yii\rest\ActiveController
,命名為 UserController
,程式碼如下:
<?php
namespace api\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'common\models\User';
}
這裡建立 user
控制器繼承 yii\rest\ActiveController
並指定要操作的模型
啟用JSON 輸入
配置 request
應用程式元件的 parsers
屬性使用 yii\web\JsonParser
用於 JSON
輸入
開啟配置檔案 api\config\main-local.php
修改為如下程式碼:
<?php
$config = [
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'P0r2XoT9LCUnyVlSgxBbJOqQxdCJ3i29',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
],
];
if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}
return $config;
配置URL規則
為剛才的 user
控制器新增url美化規則
開啟 api\config\main.php
修改 components
屬性,新增下列程式碼:
...
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'user'
],
],
]
...
ok,到此就成了一個 符合 RESTful
風格的API
看起來在控制器了什麼也沒有寫,只是指定了一個模型,但是她的背後完成了很多的功能哦,列表如下:
GET /users
: 逐頁列出所有使用者HEAD /users
: 顯示使用者列表的概要資訊POST /users
: 建立一個新使用者GET /users/123
: 返回使用者 123 的詳細資訊HEAD /users/123
: 顯示使用者 123 的概述資訊PATCH /users/123
: and PUT /users/123: 更新使用者123DELETE /users/123
: 刪除使用者123OPTIONS /users
: 顯示關於末端 /users 支援的動詞OPTIONS /users/123
: 顯示有關末端 /users/123 支援的動詞
如何訪問呢
你可以使用 curl
命令進行訪問,命令如下:
curl -i -H "Accept:application/json" "http://localhost/users"
命令列下還是比較麻煩的,也不方便測試,推薦使用 API
測試工具
這類的工具有很多,我就不一一列舉了,這裡推薦 Postman
,很好很強大,Chorme
也有外掛,可以安裝,這裡我推薦直接下載軟體安裝除錯,比較方便
你可能發現了 訪問任何路由地址都是加的s
,users
, 為什麼呢? 資源
,你要理解 資源
二字,既然是資源肯定是個集合,肯定有一大堆,所以要加上覆數,我是這麼理解的。
你說我就是不想加上s
,我就想採用http://localhost/user
這種方式來進行訪問,好吧,可以,滿足你,只是不推薦
繼續開啟配置檔案api\config\main.php
修改剛才新增的 urlManager
如下:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'user',
'pluralize' => false, //設定為false 就可以去掉複數形式了
],
],
]
加入 'pluralize' => false,
就表示去掉複數形式了,再次強調不推薦
ok,在控制器中我們沒有寫任何一句程式碼,他就給我們生成許多方法,但是有時候我們可能需要修改一些程式碼,來達到我們想要的效果,比如連表查詢,然後再返回資料
接下來我們就實現這樣的功能:
開啟剛才新建的user
控制器, 重寫 action
方法:
<?php
namespace api\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'common\models\User';
public function actions()
{
$action= parent::actions(); // TODO: Change the autogenerated stub
unset($action['index']);
unset($action['create']);
unset($action['update']);
unset($action['delete']);
return $action;
}
public function actionIndex()
{
//你的程式碼
}
}
這樣我們就可以重寫他的程式碼了。哈哈
我們再新建一個自己的 action
<?php
namespace api\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'common\models\User';
public function actions()
{
$action= parent::actions(); // TODO: Change the autogenerated stub
unset($action['index']);
unset($action['create']);
unset($action['update']);
unset($action['delete']);
return $action;
}
public function actionIndex()
{
//你的程式碼
}
public function actionSendEmail() //假如是get請求
{
//業務邏輯
}
}
然後試著訪問一下 http://localhost/users/send-email
,報錯?找不到?
報錯就對了,那是因為我們沒有設定其他路由訪問
修改 api\config\main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'user',
//'pluralize' => false, //設定為false 就可以去掉複數形式了
'extraPatterns'=>[
'GET send-email'=>'send-email'
],
],
],
]
接下來重新訪問就沒有問題了,ps:你自己編寫的任何 action
都要在 extraPatterns
進行配置
差點忘了 狀態碼
這個東西,我們現在所有的東西返回來的都是一個 JSON
,加入沒有資料局返回的是空的陣列,所以這肯定不行啊,我們得加上 一些特定的狀態碼 來標識這些資料啊,怎麼加?
繼續修改 api\config\main.php
在 components
新增如下程式碼:
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
$response = $event->sender;
$response->data = [
'success' => $response->isSuccessful,
'code' => $response->getStatusCode(),
'message' => $response->statusText,
'data' => $response->data,
];
$response->statusCode = 200;
},
],
這裡統一使用 200
來表示,當然並不是所有的都是 200,你應該具體情況具體對待,切記不要亂使用 任意加各種標識,請 遵循這些 規範 狀態碼
是不是覺得還少了點什麼?認證
對就是 認證
,就差 認證
就完美了,篇幅有限,內容多了反而影響閱讀興趣,下篇進行 認證
介紹
感謝以下,特別是 魏曦老師的影片教程
不足之處,歡迎指正
本作品採用《CC 協議》,轉載必須註明作者和本文連結