yii2框架官方说明文档 http://www.yiiframework.com/doc/guide/2.0/zh_cn/caching.page

yii2创建您的第一个application应用 http://www.yiiframework.com/doc/guide/2.0/zh_cn/quickstart.first-app

1 MVC架构

1.1处理流程

一个Web请求在Yii内部的执行流程如下图所示:

1.2组件角色

组件名

角色与责任

index.php

入口脚本。创建Application的单例对象。

application

前端控制器。分析用户请求并将其分派到合适的控制器中以作进一步处理。它同时作为服务中心,维护应用级别的配置。

request

解析用户的请求。

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/

 
 
 

版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问 http://blog.csdn.net/dc_726

yii2的更多相关文章

  1. Yii2的深入学习--行为Behavior

    我们先来看下行为在 Yii2 中的使用,如下内容摘自 Yii2中文文档 行为是 [[yii\base\Behavior]] 或其子类的实例.行为,也称为 mixins,可以无须改变类继承关系即可增强一 ...

  2. 网站实现微信登录之回调函数中登录逻辑的处理--基于yii2开发的描述

    上一篇文章网站实现微信登录之嵌入二维码中描述了如何在自己的登录页面内嵌入登录二维码,今天的这篇文章主要是描述下在扫码成功之后微信重定向回网站后登录逻辑的处理,其实也就是验证身份信息,授权用户登录的逻辑 ...

  3. 网站实现微信登录之嵌入二维码——基于yii2开发的描述

    之前写了一篇yii2获取登录前的页面url地址的文章,然后发现自己对于网站实现微信扫码登录功能的实现不是很熟悉,所以,我会写2-3篇的文章来描述下一个站点如何实现微信扫码登录的功能,来复习下微信扫码登 ...

  4. yii2获取登录前的页面url地址--电脑和微信浏览器上的实现以及yii2相关源码的学习

    对于一个有登录限制(权限限制)的网站,用户输入身份验证信息以后,验证成功后跳转到登录前的页面是一项很人性化的功能.那么获取登录前的页面地址就很关键,今天在做一个yii2项目的登录调试时发现了一些很有意 ...

  5. 记一次nginx部署yii2项目时502 bad gateway错误的排查

    周六闲来无事,就试着安装和部署下yii2,安装过程没什么问题,但部署到nginx上时遇到了502 bad gatewary问题,折腾了半天才搞定.这个问题是我以前在部署yii2时没有遇到过的,因此记在 ...

  6. yii2的权限管理系统RBAC简单介绍

    这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...

  7. yii2 RESTful api的详细使用

    作者:白狼 出处:http://www.manks.top/yii2-restful-api.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  8. yii2 ActiveRecord多表关联以及多表关联搜索的实现

    作者:白狼 出处:http://www.manks.top/yii2_many_ar_relation_search.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明 ...

  9. yii2权限控制rbac之rule详细讲解

    作者:白狼 出处:http://www.manks.top/yii2_rbac_rule.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留 ...

  10. yii2组件之多图上传插件FileInput的详细使用

    作者:白狼 出处:http://www.manks.top/yii2_multiply_images.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连 ...

随机推荐

  1. mysql 清空表 Truncate及delete区别

    1.delete from 表名[where]; 2.truncate table 表名; 3.delete将mysql表中所有记录一条一条删除到删完 4.truncate保留mysql表的结构,重新 ...

  2. 【python】aassert 断言

    语法 : assert 3>4 结果Traceback (most recent call last): File "<pyshell#0>", line 1, ...

  3. Spring实战——无需一行xml配置实现自动化注入

    已经想不起来上一次买技术相关的书是什么时候了,一直以来都习惯性的下载一份电子档看看.显然,如果不是基于强烈的需求或强大的动力鞭策下,大部分的书籍也都只是蜻蜓点水,浮光掠影. 就像有位同事说的一样,有些 ...

  4. SQL Join PK ChinaJoy

    P PK  

  5. leetcode 第一题 Two Num java

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  6. 【技术贴】解决Mysql ERROR 1045 (28000): Access denied for

    今天Mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost' 肯定是密码不对了.那么重置一下密码吧. 打开 cmd 输入以 ...

  7. HTML5的Server-Sent Events功能的使用

    客户端代码示例 //创建一个新的 EventSource 对象,然后规定发送更新的页面的 URL. var source = new EventSource("http://localhos ...

  8. [转贴]Eclipse IDE for c++配置

    从工作到现在已经有快一年多没用过C/C++了,现在想重新捡起来,但是以前一直是在windows下面进行开发,使用最多的是Eclipse和Myeclipse,因为这些都是开源的软件,并不收费,所以现在也 ...

  9. 测试用(编写优质嵌入式C程序)

    注:相比于Word,如果使用CSDN自带编辑器写出结构清晰的文档,需要花费更多的时间,所以我尝试将我写的一些word文档转换为图片发布,这样就可以保持原来的结构.字体,可以获得更好的可读性.图片的分辨 ...

  10. VC禁止在任务管理器中结束本进程

    转自百度空间:http://hi.baidu.com/175943462/item/657905e13b73b70b8d3ea8bb 一提到进程保护特别是在Windows下,没有最安全,只有更安全.下 ...