yii2

yii2框架官方說明文檔 http://www.yiiframework.com/doc/guide/2.0/zh_cn/caching.pagejavascript

yii2建立您的第一個application應用 http://www.yiiframework.com/doc/guide/2.0/zh_cn/quickstart.first-appphp

 

1 MVC架構

1.1處理流程

一個Web請求在Yii內部的執行流程以下圖所示:html

1.2組件角色

組件名前端

角色與責任java

index.phpnode

入口腳本。建立Application的單例對象。mysql

applicationgit

前端控制器。分析用戶請求並將其分派到合適的控制器中以做進一步處理。它同時做爲服務中心,維護應用級別的配置。github

requestredis

解析用戶的請求。

urlManager

幫助application決定請求的控制器和動做。

controller

執行所請求的動做,動做一般會引入所必要的模型並渲染相應的視圖,動做完成視圖渲染並將其呈現給用戶。

model

讀取數據庫或進行其餘業務操做。

view

視圖渲染出最終的頁面。

 

1.3最佳實踐

假設有這樣一個包含幾個子應用的Web應用,例如:

Ø  Front-end:面向外部用戶的Web站點

Ø  Back-end:爲管理員提供管理功能的Web站點

Ø  Console:在終端中做爲定時做業執行

Ø  Web API:爲第三方提供集成的API

1.3.1 Model

Ø  包含表明特定數據的屬性

Ø  包含業務邏輯、驗證規則

Ø  包含操縱數據的代碼

Ø  不該使用$_GET,$_POST等與界面類型綁定的變量

Ø  避免嵌入HTML等展現層代碼

 

有時聽從第三條「包含操縱數據的代碼」會讓Model層變得很胖,所以能夠爲不一樣的子應用提供不一樣的Model子類。例如定義一個NewsBase類包含跨子應用共享的代碼,爲每一個子應用實現本身的Model類,只包含針對當前子應用的代碼。

1.3.2 View

Ø  包含展現代碼,例如HTML和簡單的遍歷、格式化、渲染PHP代碼

Ø  避免包含顯示訪問數據的代碼

Ø  避免直接訪問$_GET,$POST等變量

 

視圖層的代碼重用方式:

Ø  佈局:公共展現區域(如頁眉、頁腳)能夠放在一個佈局視圖中

Ø  部分視圖:非佈局代碼的代碼片斷能夠經過部分視圖重用,例如表單代碼

Ø  控件:若是部分視圖中包含大量邏輯,就能夠提取爲控件類來重用。

Ø  助手類:完成細小任務的代碼能夠用助手類來重用,例如格式化數據,產生HTML標籤

1.3.3 Controller

Ø  能夠訪問$_GET,$_POST等PHP變量來得到用戶請求

Ø  建立Model實例,並管理其生命週期

Ø  避免嵌入SQL語句

Ø  避免包含HTML等展現層代碼

 

在設計良好的MVC應用程序中,控制器經過很是瘦,只包含幾十行代碼。然而模型層一般會很胖,由於它包含了不一樣領域的業務邏輯,知足特定的需求。

 

2應用組件擴展

Yii 預約義了一系列核心應用組件,提供常見Web 應用中所用的功能。像【1.1組件角色】中的urlManager,【3數據訪問】中將用到的CDbConnection,以及對Memcached支持等等都是經過可擴展的應用組件的形式加入到Yii中的。

2.1內置應用組件

下面咱們列出了由 CWebApplication 預約義的核心組件。

·        assetManagerCAssetManager -管理私有資源文件的發佈。

·        authManagerCAuthManager -管理基於角色的訪問控制(RBAC).

·        cacheCCache -提供數據緩存功能。注意,你必須指定實際的類(例如CMemCacheCDbCache)。不然,當你訪問此組件時將返回 NULL。

·        clientScriptCClientScript -管理客戶端腳本(javascripts 和CSS).

·        coreMessagesCPhpMessageSource -提供 Yii 框架用到的核心信息的翻譯。

·        dbCDbConnection -提供數據庫鏈接。注意,使用此組件你必須配置其 connectionString 屬性。

·        errorHandlerCErrorHandler -處理未捕獲的 PHP 錯誤和異常。

·        formatCFormatter -格式化數值顯示。此功能從版本1.1.0 起開始提供。

·        messagesCPhpMessageSource -提供Yii應用中使用的信息翻譯。

·        requestCHttpRequest -提供關於用戶請求的信息。

·        securityManagerCSecurityManager -提供安全相關的服務,例如散列,加密。

·        sessionCHttpSession -提供session相關的功能。

·        statePersisterCStatePersister -提供全局狀態持久方法。

·        urlManagerCUrlManager -提供 URL 解析和建立相關功能

·        userCWebUser -提供當前用戶的識別信息。

·        themeManagerCThemeManager -管理主題。

 

2.2激活應用組件

要激活應用組件,咱們須要定製Application。方式一是提供一個配置文件以建立Application實例時初始化其屬性值;另外一種方式是繼承CWebApplication。

 

咱們一般採用方式一,在一個單獨的PHP腳本(例如protected/config/main.php)中保存這些配置。要激活某個應用組件,咱們須要在這個PHP腳本中配置Application的components屬性。例以下面激活memcached組件實現緩存功能:

array(

   ......

    'components'=>array(

       ......

       'cache'=>array(

           'class'=>'CMemCache',

           'servers'=>array(

                array('host'=>'server1', 'port'=>11211, 'weight'=>60),

                array('host'=>'server2', 'port'=>11211, 'weight'=>40),

           ),

       ),

    ),

)

 

而後在入口腳本index.php中,將配置文件的名字做爲參數傳遞給應用構造器:

$app=Yii::createWebApplication($configFile);

 

如今就能夠訪問應用組件了。使用Yii::app()->ComponentID,其中的ComponentID是指組件的ID(例如Yii::app()->cache)。

3數據訪問方式

Yii數據訪問創建在PHP的PDO擴展上,經過一個統一的接口訪問不一樣的數據庫。在此基礎上,Yii提供了三種數據庫編程方式。

3.1直接使用核心類

Yii DAO 主要包含以下四個類:

CDbConnection:表明一個數據庫鏈接。

CDbCommand:表明一條經過數據庫執行的SQL 語句。

CDbDataReader:表明一個只向前移動的,來自一個查詢結果集中的行的流。

CDbTransaction:表明一個數據庫事務。

使用方法與Java的JDBC很像,例如:

 

$connection=Yii::app()->db;   
$command=$connection->createCommand($sql);
 
// 查詢
$dataReader=$command->query();
while(($row=$dataReader->read())!==false){ ... }
// 綁定參數
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// 用實際的用戶名替換佔位符 ":username" 
$command->bindParam(":username",$username,PDO::PARAM_STR);
// 用實際的 Email 替換佔位符 ":email" 
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();

 

3.2查詢構造器

Yii的查詢構造器(Query Builder)提供了面向對象方式編寫SQL語句。例如:

 

$user = Yii::app()->db->createCommand()
    ->select('id, username, profile')
    ->from('tbl_user u')
    ->join('tbl_profile p', 'u.id=p.user_id')
    ->where('id=:id', array(':id'=>$id))
    ->queryRow();

 

對於比較簡單的SQL語句來講,使用這種方式編程的優勢有:

Ø  提升代碼可讀性

Ø  參數綁定避免SQL注入攻擊

Ø  在PDO基礎上的進一步數據庫抽象,簡化數據遷移

3.3活動對象模式

雖然前兩種方式已經能夠處理幾乎任何數據庫相關的任務,但極可能咱們會花費90%的時間以編寫一些執行普通CRUD操做的SQL語句。並且咱們代碼中混雜的SQL語句也會使代碼變得難以維護。要解決這些問題,咱們可使用活動對象模式(Active Record,簡稱AR)。

 

AR是一個流行的對象-關係映射(ORM)技術。每一個AR類表明一個數據表,數據表的列在 AR 類中體現爲類的屬性,一個AR實例則表示表中的一行。常見的CRUD操做做爲AR的方法實現。所以,咱們能夠以一種更加面向對象的方式訪問數據。

 

classPostextendsCActiveRecord
{
    publicstaticfunctionmodel($className=__CLASS__)
    {
        returnparent::model($className);
    }
    publicfunctiontableName()
    {
        return'tbl_post';
    }
}
 
$post=newPost;
$post->title='sample post';
$post->content='post body content';
$post->save();

 

具體例子見【6.2模型層實例】。

4數據緩存支持

Yii 提供了不一樣的緩存組件,能夠將緩存數據存儲到不一樣的媒介中。例如, CMemCache 組件封裝了 PHP 的 memcache 擴展並使用內存做爲緩存存儲媒介。 CApcCache 組件封裝了 PHP APC 擴展; 而 CDbCache 組件會將緩存的數據存入數據庫。下面是一個可用緩存組件的列表:

·        CMemCache:使用 PHP memcache 擴展.

·        CApcCache:使用 PHP APC 擴展.

·        CXCache:使用 PHP XCache 擴展。注意,這個是從 1.0.1 版本開始支持的。

·        CEAcceleratorCache:使用 PHP EAccelerator 擴展.

·        CDbCache:使用一個數據表存儲緩存數據。默認狀況下,它將建立並使用在runtime 目錄下的一個SQLite3 數據庫。你也能夠經過設置其 connectionID 屬性指定一個給它使用的數據庫。

·        CZendDataCache:使用 ZendData Cache 做爲後臺緩存媒介。注意,這個是從1.0.4 版本開始支持的。

·        CFileCache:使用文件存儲緩存數據。這個特別適合用於存儲大塊數據(例如頁面)。注意,這個是從1.0.6 版本開始支持的。

·        CDummyCache:目前 dummy 緩存並不實現緩存功能。此組件的目的是用於簡化那些須要檢查緩存可用性的代碼。例如,在開發階段或者服務器還沒有支持實際的緩存功能,咱們可使用此緩存組件。當啓用了實際的緩存支持後,咱們能夠切換到使用相應的緩存組件。在這兩種狀況中,咱們可使用一樣的代碼Yii::app()->cache->get($key) 獲取數據片斷而不須要擔憂 Yii::app()->cache 可能會是 null。此組件從 1.0.5 版開始支持。

 

4代碼生成工具

(TODO 介紹Yii和Gii,能夠用來快速開發系統原型)

5單元測試框架

(TODO 介紹基於PHPUnit的單元測試)

6一個典型例子

在《Yii入門實例.docx》的基礎上增長下面三個實例。

演示程序的總體目錄結構以下:

app/

|-- index.php

`-- protected

    |-- config

    |   `-- main.php

    |-- controllers

    |   |-- CacheController.php

    |   |-- HelloController.php

    |   |-- PostController.php

    |   |-- route

    |   |  |-- CreateAction.php

    |   |  |-- DeleteAction.php

    |   |  `-- UpdateAction.php

    |   `-- RouteController.php

    |-- extensions

    |   `-- redis

    |       |-- CRedisCache_old.php

    |       |-- CRedisCache.php

    |       `-- Predis.php

    |-- filters

    |   `-- PerfFilter.php

    |-- models

    |   `-- Post.php

    `-- views

        |-- cache

        |   `-- result.php

        |-- hello

        |   `-- result.php

        |-- post

        |   `-- result.php

        `-- route

            `-- result.php

6.1控制器層實例

此控制器層實例主要演示三方面:

Ø  請求參數自動綁定到方法形參

Ø  獨立的Action類替代action方法

Ø  使用過濾器實現關注點分離

 

1.helloyii/app/protected/controllers/RouteController.php

===============================================================================

         classRouteController extends CController

         {

                   publicfunction actions()

                   {

                            $path= 'application.controllers.route.';

                            returnarray(

                                     'create'=>$path.'CreateAction',

                                     'update'=>$path.'UpdateAction',

                                     'delete'=>$path.'DeleteAction',

                            );

                   }

 

                   publicfunction filters()

                   {

                            returnarray(

                                     array('application.filters.PerfFilter'),

                            );

                   }

         }

 

2.helloyii/app/protected/controllers/route/DeleteAction.php

===============================================================================

       class DeleteAction extends CAction        //2.獨立的Action類

       {

                public function run($id)    //1.$_GET請求中的參數自動綁定到方法形參

                {

                        $data = "This isDeleteAction served you, id:$id";

                       Yii::app()->getController()->render('result',array('data'=>$data));

                }

       }

如今訪問http://helloyii.com/app/index.php?r=route/delete&id=1就能看到效果。

注:CreateAction.php和UpdateAction.php的代碼與之相似,就不列舉了。

 

3.helloyii/app/protected/filters/PerfFilter.php

===============================================================================

         classPerfFilter extends CFilter                  //3.實現過濾器抽象類,對Action進行先後處理

         {

                   protectedfunction preFilter($filterChain)

                   {

                            echo'PerfFilter pre action<br/>';

                            returntrue;

                   }

 

                   protectedfunction postFilter($filterChain)

                   {

                            echo'<br/>PerFilter post action';

                            returntrue;

                   }

         }

 

4.helloyii/app/protected/views/route/result.php

===============================================================================

<?php

         echo$data;

?>

6.2模型層實例

首先建立數據庫helloyii,在其中建立一張新表用來演示。

 

CREATETABLEtbl_post(
    idINTEGERNOTNULLPRIMARYKEYAUTO_INCREMENT,
    titleVARCHAR(128)NOTNULL,
    contentTEXTNOTNULL,
    create_timeINTEGERNOTNULL
);

 

1.helloyii/app/protected/config/main.php

===============================================================================

       return array(

                'components' => array(

                        'db' => array(

                               'connectionString' =>'mysql:host=localhost;port=3306;dbname=helloyii;',

                               'emulatePrepare' => true,

                                'username'=> 'root',

                                'password'=> '',

                                'charset' =>'utf8',

                        ),

                ),

                'import'=>array(

                        'application.models.*',

                ),

       );

注意:使用main.php對應用進行配置的話,要修改入口腳本index.php:

         $config=dirname(__FILE__).'/protected/config/main.php';

         Yii::createWebApplication($config)->run();

 

2.helloyii/app/protected/controllers/RouteController.php

===============================================================================

       class PostController extends CController

       {

                public function actionQuery()

                {

                        // Insert one row totable

                        $post = new Post;

                        $post->title ='sample post';

                        $post->content ='content for sample post';

                        $post->create_time =time();

                        $post->save();

 

                        // Query all rows intable

                        $data =Post::model()->findAll();

 

                        //Delegate viewer torender

                       Yii::app()->getController()->render('result',array('data'=>$data));

                }

       }

 

3.helloyii/app/protected/models/Post.php

===============================================================================

       class Post extends CActiveRecord

       {

                public static functionmodel($className=__CLASS__)

                {

                        returnparent::model($className);

                }

 

                public function tableName()

                {

                        return 'tbl_post';     //對應數據庫中的表名

                }

       }

 

4.helloyii/app/protected/views/post/result.php

===============================================================================

<html>

<head></head>

<body>

       <table border="1">

       <tr>

                <th>ID</th>

                <th>Title</th>

                <th>Content</th>

                <th>CreateTime</th>

       </tr>

<?php

       foreach ($data as $row)

       {

                echo "<tr>";

                echo"<td>".$row->id."</td>";

                echo"<td>".$row->title."</td>";

                echo"<td>".$row->content."</td>";

                echo"<td>".$row->create_time."</td>";

                echo "</tr>";

       }

?>

 

       </table>

</body>

</html>

 

如今訪問http://helloyii.com/app/index.php?r=post/query,效果以下圖:

 

6.3數據緩存實例

詳見《Yii集成Redis》。

參考資料

1 Yii的控制器官方介紹

http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.controller

 

2 MVC最佳實踐官方介紹

http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.best-practices

 

1安裝Redis

切換至/usr/local/src下,下載並安裝redis:

$ wgethttp://redis.googlecode.com/files/redis-2.6.12.tar.gz

$ tar xzf redis-2.6.12.tar.gz

$ cd redis-2.6.12

$ make

 

進入redis-2.6.12目錄,修改redis.conf:

daemonize yes

 

啓動服務端:

$src/redis-server redis.conf

 

進入命令行驗證服務是否啓動:

         $src/redis-cli

redis> set foo bar

OK

redis> get foo

"bar"

2安裝Yii的Redis插件

目前主要有兩種Yii插件:

Ø  Rediscache:基於predis(Redis的純PHP實現客戶端),無需安裝Redis for PHP擴展。

Ø  YiiRedis:基於phpredis客戶端,須要安裝Redis for PHP擴展。

這裏採用Rediscache插件,避免線上安裝Redis for PHP擴展。

2.1下載安裝

從如下地址下載Rediscache插件:

http://www.yiiframework.com/extension/rediscache/files/redis.zip

 

將插件解壓到helloyii/app/protected/extensions中:

 

插件文件部署後的位置應爲:helloyii/app/protected/extensions/redis/CredisCache.php

2.2配置Rediscache

1.helloyii/app/protected/config/main.php

===============================================================================

 return array(

 'components' => array(

   …

   'cache'=>array(

    'class'=>'ext.redis.CRedisCache',     //對應protected/extensions/redis/CredisCache.php

    'servers'=>array(

     array(

      'host'=>'127.0.0.1',

      'port'=>6379,

     ),

    ),

   ),

  ),

  …

 );

3安裝Yii的會話Redis插件

3.1下載安裝

從GitHub上下載插件https://github.com/lincsanders/PRedisCacheHttpSession

 

解壓到helloyii/app/protected/extensions下:

 

插件文件部署後的位置應爲:

         helloyii/app/protected/extensions/PredisCacheHttpSession/PRedisCacheHttpSession.php

3.2配置PRedisCacheHttpSession

'session'=>array(

'class' =>'ext.PRedisCacheHttpSession.PRedisCacheHttpSession',

'database' => 9,

),

注意:緩存和會話的database屬性必定要區分開,用不一樣的Redis數據庫來保存。

4編寫控制器

編寫一個讀寫緩存的控制器進行測試。

 

2.helloyii/app/protected/controllers/CacheController.php

===============================================================================

class CacheController extends CController

{

 public function actionFetch($key, $value)

  {

  Yii::app()->cache->set($key, $value);

  $data = Yii::app()->cache->get($key);

  Yii::app()->getController()->render('result',array('data'=>$data));

  }

}

 

3.helloyii/app/protected/views/cache/result.php

===============================================================================

<?php

 echo$data;

?>

 

如今訪問:http://helloyii.com/app/index.php?r=cache/fetch&key=a&value=b

而後經過redis-cli命令行客戶端查看下緩存的變化:

能夠經過redis-cli客戶端查看緩存:

$ src/redis-cli

redis> keys ‘*’

 

參考資料

1官方安裝手冊

http://redis.io/download

 

2 Yii的Redis插件1:rediscache

http://www.yiiframework.com/extension/rediscache/

 

3 Yii的Redis插件2:yiiredis

https://github.com/phpnode/YiiRedis

 

4 Yii CCache接口的API

http://www.yiichina.com/api/CCache#get-detail

 

5 Redis在YiiFramework中的使用

http://denghai260.blog.163.com/blog/static/726864092012323101628773/

相關文章
相關標籤/搜索