最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Yii2中Restful API原理實例分析

 更新時間:2016年07月25日 10:47:42   作者:wjtlht928  
這篇文章主要介紹了Yii2中Restful API原理,基于rest部分源碼分析了Restful的原理、使用方法與相關(guān)注意事項,需要的朋友可以參考下

本文實例分析了Yii2中Restful API原理。分享給大家供大家參考,具體如下:

Yii2 有個很重要的特性是對 Restful API的默認支持, 通過短短的幾個配置就可以實現(xiàn)簡單的對現(xiàn)有Model的RESTful API

這里通過分析rest部分源碼,簡單剖析下yii2 實現(xiàn) restful 的原理,并通過一些定制實現(xiàn) 對 關(guān)聯(lián)模型的RESTful api 操作。

~ 代表 extends from 的關(guān)系

| | rest/
| | |-Action.php ~ `\yii\base\Action`
| | |-Controller.php ~  `\yii\web\Controller`
| | | |-ActiveController.php ~ `rest\Controller`
| | |-Serializer.php ~ `yii\base\Component`
| | |-UrlRule.php ~ `yii\web\CompositeUrlRule`
| | |-CreateAction.php ~ `rest\Action`
| | |-DeleteAction.php ~ `rest\Action`
| | |-IndexAction.php ~ `rest\Action`
| | |-OptionsAction.php ~ `rest\Action`
| | |-UpdateAction.php ~ `rest\Action`
| | |-ViewAction.php ~ `rest\Action`

1. rest/Controller ~ \yii\web\Controller

Controller是 RESTful API 控制器類的基類

它在一個API請求的控制周期中一次實現(xiàn)了下面的步驟 1~5:

① 解析響應(yīng)的內(nèi)容格式
② 校驗請求方法
③ 檢驗用戶權(quán)限
④ 限制速度
⑤ 格式化響應(yīng)數(shù)據(jù)

use yii\filters\auth\CompositeAuth;
use yii\filters\ContentNegotiator;
use yii\filters\RateLimiter;
use yii\web\Response;
use yii\filters\VerbFilter;
/**
 * Controller is the base class for RESTful API controller classes.
 *
 * Controller implements the following steps in a RESTful API request handling cycle
 * 1. Resolving response format (see [[ContentNegotiator]]);
 * 2. Validating request method (see [[verbs()]]).
 * 3. Authenticating user (see [[\yii\filters\auth\AuthInterface]]);
 * 4. Rate limiting (see [[RateLimiter]]);
 * 5. Formatting response data (see [[serializeData()]])
behaviors
  contentNegotiator
  verbFilter
  authenticator
  rateLimiter
afterAction
  serializeData Yii::createObject($this->serializer)->serialize($data)
verbs []
*/
class Controller extends \yii\web\Controller
{
  public $serializer = 'yii\rest\Serializer';
  public $enableCsrfValidation = false;
  public function behaviors()
  {
    return [
      'contentNegotiator' => [
        'class' => ContentNegotiator::className(),
        'formats' => [
          'application/json' => Response::FORMAT_JSON,
          'application/xml' => Response::FORMAT_XML,
        ],
      ],
      'verbFilter' => [
        'class' => VerbFilter::className(),
        'actions' => $this->verbs(),
      ],
      'authenticator' => [
        'class' => CompositeAuth::className(),
      ],
      'rateLimiter' => [
        'class' => RateLimiter::className(),
      ],
    ]
  }
  public function verbs()
  {
    return [];
  }
  public function serializeData($data)
  {
    return Yii::createObject($this->serializer)->serialize($data);
  }
  public function afterAction($action, $result)
  {
    $result = parent::afterAction($action, $result);
    return $this->serializeData($result);
  }
}

2. rest/ActiveController ~ rest/Controller

ActiveController 實現(xiàn)了一系列的和 ActiveRecord 互通數(shù)據(jù)的RESTful方法

ActiveRecord 的類名由 modelClass 變量指明, yii\db\ActiveRecordInterface ???

默認的, 支持下面的方法:

 * - `index`: list of models
 * - `view`: return the details of a model
 * - `create`: create a new model
 * - `update`: update an existing model
 * - `delete`: delete an existing model
 * - `options`: return the allowed HTTP methods

可以通過覆蓋 actions() 并且 unsetting 響應(yīng)的 action 來禁用這些默認的動作。

要增加一個新的動作, 覆蓋 actions() 向其末尾增加一個新的 action class 或者 是一個新的 action method

注意一點,確保你同時也覆蓋了 verbs() 方法來聲明這個新的動作支持那些HTTP Method

也需要覆蓋checkAccess() 來檢查當(dāng)前用戶是否有權(quán)限來執(zhí)行響應(yīng)的某個動作。

根據(jù)上面的說明再寫一遍 Controller

class ActiveController extends Controller
{
  public #modelClass;
  public $updateScenario = Model::SCENARIO_DEFAULT;
  public $createScenario = Model::SCENARIO_DEFAULT;
  public function init()
  {
    parent::init();
    if($this->modelClass == null){
      throw new InvalidConfigException('The "modelClass" property must be set.');
    }
  }
  public function actions()
  {
    return [
      'index' => [
        'class' => 'app\controllers\rest\IndexAction',
        'modelClass' => $this->modelClass,
        'checkAccess' => [$this, 'checkAccess'],
      ],
      'view'...
      'create'...
      'update'...
      'delete'...
      'options'...
    ];
  }
  protected function verbs()
  {
    return [
      'index' => ['GET', 'HEAD'],
      'view' =>['GET', 'HEAD'],
      'create' =>['POST'],
      'update' =>['PUT', 'PATCH'],
      'delete' =>['DELETE'],
    ];
  }
  public function checkAccess($action, $model=null, $params = [])
  {
  }
}

下面來實現(xiàn)一個繼承自 這個rest\ActiveController的 News 控制器:

namespace app\controllers;
use app\controllers\rest\ActiveController; #剛才這個AC,我從yii/rest下面拷貝了一份出來
class NewsController extends ActiveController
{
  public $modelClass ='app\models\News';
}

定義到這里就足夠?qū)崿F(xiàn) rest\ActiveController 里面的默認方法了
下面來覆蓋下,實現(xiàn)一些定制的方法

class NewsController extends ActiveController
{
  public $modelClass = 'app\models\News';
  #定制serializer
  #public $serializer = 'yii\rest\Serializer';
  public $serializer = [
    'class' => 'app\controllers\rest\Serializer',
    'collectionEnvelope' => 'items',
  ];
  public function behaviors()
  {
    $be = ArrayHelper::merge(
      parent::behaviors(),
      [
        'verbFilter' => [
          'class' => VerbFilter::className(),
          'actions' => [
            'index' => ['get'],
            ...
          ]
        ],
        'authenticator' => [
          'class' => CompositeAuth::className(),
          'authMethods' => [
            HttpBasicAuth::className(),
            HttpBearerAuth::className(),
            QueryParamAuth::className(),
          ]
        ],
        'contentNegotiator' => [
          'class' => ContentNegotiator::className(),
          'formats' => [
            'text/html' => Response::FORMAT_HTML,
          ]
        ],
        'access' => [
          'class' => AccessControl::className(),
          'only' => ['view'],
          'rules' => [
            [
             'actions' => ['view'],
             'allow' => false,
             'roles' => ['@'],
            ],
         ],
        ]
      ],
    );
    return $be;
  }
  public function checkAccess()
  {
  }
}

3. 定制Actions

如果要對 Actions 進行大的改動,建議拷貝一份出來,不要使用原始的 yii\rest\XXXAction命名空間

我這里以要實現(xiàn)對related models進行 CURD 操作為目標(biāo)進行大的改動

Action

在定制各個action之前, 先看看它們的基類 rest\Action, 主要是一個 findModel的方法

class Action extend \yii\base\Action
{
  public $modelClass;
  public $findModel;
  public $checkAccess;
  public function init()
  {
    if($this->modelClass == null) {
      throw new InvalidConfigException(get_class($this). '::$modelClass must be set');
    }
  }
  public function findModel($id)
  {
    if($this->findModel !== null) {
      return call_user_func($this->findModel, $id, $this);
    }
    $modelClass = $this->modelClass;
    $keys = $modelClass::primaryKey();
    if(count($keys) > 1) {
      $values = explode(',', $id);
      if..
    } elseif($id !== null) {
      $model = $modelClass::findOne($id);
    }
    if(isset($model)){
      return $model;
    }else {
      throw new NotFoundHttpException("Object not found: $id");
    }
  }
}

view

view 動作不需要改動,因為 model 有 getRelated 的自有機制

class ViewAction extend Action
{
  public function run($id)
  {
    $model = $this->findModel($id);
    if($this->checkAccess) {
      call_user_func($this->checkAccess, $this->id, $model);
    }
  }
}

update

public function run($id)
{
  /* @var $model ActiveRecord */
  $model = $this->findModel($id);
  if ($this->checkAccess) {
   call_user_func($this->checkAccess, $this->id, $model);
  }
  $model->scenario = $this->scenario;
  $model->load(Yii::$app->getRequest()->getBodyParams(), '');
  $model->save();
  return $model;
}

經(jīng)過改造后,需要滿足對關(guān)聯(lián)模型的update動作

public function run($id)
{
  /* @var $model ActiveRecord */
  $model = $this->findModel($id);
  if ($this->checkAccess) {
   call_user_func($this->checkAccess, $this->id, $model);
  }
  $model->scenario = $this->scenario;
    /*
     *
     * x-www-form-urlencoded key=>value
     * image mmmmmmmm
     * link nnnnnnnnnn
     * newsItem[title]=>ttttttttttt , don't use newsItem["title"]
     * newsItem[body]=>bbbbbbbbbbb
     * don't use newsItem=>array("title":"tttttt","body":"bbbbbbb")
     * don't use newsItem=>{"title":"ttttttt","body":"bbbbbbbb"}
     *
     */
    $newsItem = Yii::$app->getRequest()->getBodyParams()['newsItem'];
    /*
      Array
      (
        [title] => ttttttttttt
        [body] => bbbbbbbbbbb
      )
     */
    $model->newsItem->load($newsItem, '');
    #$model->newsItem->load(Yii::$app->getRequest()->getBodyParams(), '');
    #print_R($model->newsItem);exit;
    #print_R($model->newsItem);exit;
    if($model->save())
    {
      $model->load(Yii::$app->getRequest()->getBodyParams(), '');
      $model->newsItem->save();
    }
  return $model;
}

這里還應(yīng)該對 newsItem save 失敗 的情況進行處理,暫且不處理。

更多關(guān)于Yii相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Yii框架入門及常用技巧總結(jié)》、《php優(yōu)秀開發(fā)框架總結(jié)》、《smarty模板入門基礎(chǔ)教程》、《php面向?qū)ο蟪绦蛟O(shè)計入門教程》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總

希望本文所述對大家基于Yii框架的PHP程序設(shè)計有所幫助。

相關(guān)文章

  • 學(xué)習(xí)php中的正則表達式

    學(xué)習(xí)php中的正則表達式

    簡單的說,正則表達式是一種可以用于模式匹配和替換的強有力的工具。我們可以在幾乎所有的基于UNIX系統(tǒng)的工具中找到ta的身影。此外,象JavaScript這種客戶端的腳本語言也提供了支持。正則表達式已經(jīng)超出了某種語言或某個系統(tǒng)的局限,成為人們廣為接受的概念和功能。
    2014-08-08
  • PHP dirname功能及原理實例解析

    PHP dirname功能及原理實例解析

    這篇文章主要介紹了PHP dirname功能及原理實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • thinkPHP模板中for循環(huán)與switch語句用法示例

    thinkPHP模板中for循環(huán)與switch語句用法示例

    這篇文章主要介紹了thinkPHP模板中for循環(huán)與switch語句用法,結(jié)合實例形式分析了for循環(huán)與switch語句的具體功能、定義與具體使用技巧,需要的朋友可以參考下
    2016-11-11
  • PHP可變變量學(xué)習(xí)小結(jié)

    PHP可變變量學(xué)習(xí)小結(jié)

    可變變量,就是一個變量的變量名可以動態(tài)的設(shè)置和使用。語法形式是PHP的特殊語法,其他語言中少見,本文給大家分享php可變變量學(xué)習(xí)小結(jié),對php可變變量相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • laravel日志優(yōu)化實例講解

    laravel日志優(yōu)化實例講解

    這篇文章主要介紹了laravel日志優(yōu)化實例講解,日志是查找代碼問題的重要的文件,有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03
  • php實現(xiàn)smarty模板無限極分類的方法

    php實現(xiàn)smarty模板無限極分類的方法

    這篇文章主要介紹了php實現(xiàn)smarty模板無限極分類的方法,結(jié)合實例形式較為詳細的分析了php使用smarty模板實現(xiàn)數(shù)據(jù)庫查詢與無限極分類的相關(guān)技巧,需要的朋友可以參考下
    2015-12-12
  • laravel 模型查詢按照whereIn排序的示例

    laravel 模型查詢按照whereIn排序的示例

    今天小編就為大家分享一篇laravel 模型查詢按照whereIn排序的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • WordPress后臺中實現(xiàn)圖片上傳功能的實例講解

    WordPress后臺中實現(xiàn)圖片上傳功能的實例講解

    這篇文章主要介紹了WordPress后臺中實現(xiàn)圖片上傳功能的實例講解,包括多個圖片上傳表單功能的實現(xiàn),需要的朋友可以參考下
    2016-01-01
  • PHP實現(xiàn)的帶超時功能get_headers函數(shù)

    PHP實現(xiàn)的帶超時功能get_headers函數(shù)

    這篇文章主要介紹了PHP實現(xiàn)的帶超時功能的get_headers函數(shù),本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-02-02
  • php操作memcache緩存方法分享

    php操作memcache緩存方法分享

    一般來說,如果并發(fā)量不大的情況,使不使用緩存技術(shù)并沒有什么影響,但如果高并發(fā)的情況,使用緩存技術(shù)就顯得很重要了,可以很好的減輕數(shù)據(jù)庫和服務(wù)器的壓力,當(dāng)然解決高并發(fā)的技術(shù)有很多,這里只是以緩存的角度來說明使用memcache的便捷性和方便性,
    2015-06-06

最新評論

和田市| 信宜市| 手机| 集安市| 高州市| 诏安县| 沈阳市| 阳谷县| 仙桃市| 永德县| 偏关县| 高阳县| 高台县| 永川市| 定安县| 淄博市| 洞口县| 彭山县| 安岳县| 五河县| 佛山市| 寿光市| 高州市| 武强县| 永寿县| 垦利县| 沾益县| 永川市| 邯郸市| 民县| 湄潭县| 大邑县| 新疆| 垫江县| 子洲县| 和林格尔县| 任丘市| 洛川县| 永胜县| 新和县| 利川市|