视图调用视图:
在controller中使用return $this->renderPartial('index');//表示渲染index视图
在视图文件index.php中写入<h1>hello index</h1>
在视图文件about.php中写入<h1>hello about</h1>
在视图文件index.php中调用视图文件about.php 添加如下代码
<?php echo $this->render('about',array('v_hello_str'=>'hello world'));?>
在about视图文件中添加入下代码:
<h1><?=$v_hello_str; ?></h1>
在浏览器调用index视图就可以实现视图调用视图
布局文件:
将index.php视图文件和about.php视图文件的公共部分删除放入到layout.php(默认渲染)中
在controller中使用return $this->render('index'); //render将视图文件的内容放入到$content中
还可以添加一个属性指定布局文件 public $layout='common'; 将使用layout/common.php进行渲染
数据块:
在视图文件定义数据块,可以覆盖布局文件相应的块
在index.php视图文件中定义如下代码:
<?php $this->beginBlock('block1'); ?>
<h1>index</h1>
<?php $this->endBlock(); ?>
在布局文件相应的地方写入如下代码进行调用:
<?=$this->blocks['block1']; ?>
也可以进行判断:
<?php if(isset($this->blocks['block1'])): ?>
<?=$this->blocks['block1']; ?>
<?php else: ?>
<h1>hello Common</h1>
<?php endif; ?>
命名空间:
顶级的类只需要在类名前加入一个反斜线,便可以new一个对象。
其他类使用use关键字,也可以区别名,例如:
use a\b\c\Apple;
use d\e\f\Apple as BApple;
$a=new Apple();
$b=new BApple();
$c=new \Apple();
响应:
$res= \YII::$app->response;
$res->statusCode='404'; //设置状态码
$res->headers->add('pragma','no-cache'); //设置http头
$res->headers->set('pragma','max-age=5');
$res->headers->remove('pragma');
//跳转
$res->header->add('location','http://www.baidu.com');
$this->redirect('http://www.baidu.com',302);
//文件下载
$res->headers->addd('content-disposition','attachment; filename="a.jpg"');
$res->sendFile('/robots.txt'); //找入口文件路劲下的文件
session:
$session=\YII::$app->session;
$session->open();
if($session->isActive){
echo 'session is active';
}
$session->set('user','张三');
echo $session->get('user');
$session->remove('user');
$session['user']='张三';
echo $session['user'];
unset($session['user']);
cookie:
$cookies=\YII::$app->response->cookies;
$cookie_data=array('name'=>'user','value'=>'zhangsi');
$cookies->add(new Cookie($cookie_data));
$cookies->remove('is');
$cookies=\YII::$app->request->cookies;
echo $cookies->getValue('user',20);
renderPartial渲染一个视图并传递参数
在controllers中:$hello_str="Hello God!";
//创建一个数组
$data=array();
//把需要传递给视图的数据,放到数组当中
$data['view_hello_str']=$hello_str;
return $this->renderPartial('index',$data);
在视图中使用如下方法输出
<?=$view_hello_str;?>
多个数据可以使用:<?=$view_test_arr[0];?>数组形式输出
//过滤js代码,但是可以当字符串输出
<?=Html::encode($view_hello_str);?>
//过滤js,没有js代码的输出
<?=HtmlPurifier::process($view_hello_str);?>
查询数据:
应当在config/db.php 配置数据库
在models下建立一个与表名一样的.php文件
在controllers中如下:
$sql="select * from test where id=1";
$result=Test::findBySql($sql)->all();
print_r($result);
//$id='1 or 1=1';
$sql='select * form test where id=:id";
$result=Test::findBySql($sql,array(':id'=>1))->all();
$result=Test::findBySql($sql,array(':id'=>'1 or 1=1'))->all();
print_r($result);
//id=1
$results=Test::find()->where(['id'=>1])->all();
//id>0
$results=Test::find()->where(['>','id',0])->all();
//id>=1 并且id<=2
$results=Test::find()->where(['between','id',1,2])->all();
//title like "%title%"
$results=Test::find()->where(['like','title','title'])->all();
//查询结果转换成数组,对象比较占内存
$resulr=Test::find()->where([''between','id',1,2])->asArray()->all();
//批量查询
foreach(Test::find()->batch(1) as $test){
print_r(count($test));
}
//删除数据
$results=Test::find()->where(['id'=>1])->all();
$results[0]->delete();
Test::deleteAll('id>:id',array(':id'=>0));
增加数据
$test=new Test();
$test->id=3;
$test->title='title3';
$test->validate(); //进行规则验证
if($test->hasErrors()){
echo 'data is error';
}
$test->save();
//修改数据
$test-Test::find()->where(['id'=>4])->one();
$test->title='title4';
$test->save();
//关联查询
models/Customer.php
public function getOrders(){
$orders=$this->hasMany(Order::className,['customer_id'=>'id'])->asArray()->all();
return $orders;
}
models/Order.php
public function getCustomer(){
return $this->hasOne(Customer::className(),['id'=>'customer_id')->asArray();
}
controllers/HelloControllers.php
public function actionIndex(){
//根据顾客信息查询她/他的订单信息
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//customer_id在app\models\Order表中,ID在Customer表中
$orders=$customer->hasMany('app\models\Order',['customer_id'=>'id'])->asArray()->all();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//$orders=$customer->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
$orders=$customer->getOrders();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->orders; //调用魔术方法__get,之后调用getOrders()(自己实现),之后再查询结果后面加调用all()
//根据订单查询顾客的信息
$order=Order::find()->where(['id'=>1])->one();
$customer=$order->customer;
print_r($customer);
//关联查询的多次查询(N+1次)
$customers=Customer::find()->where('orders')->all(); //select * from customer;
foreach($customers as $customer){
$orders=$customer->orders; //select * from order where customer_id =....
}
//关联查询的多次查询(2次)
//select * from customer;
//select * from order where customer_in in ....;
$customers=Customer::find()->with('order')->all();
foreach($customers as $customer){
$orders=$customer->orders;
}
}
类的自动加载:
存在class/class1.php class/class2.php 和index.php
在index.php中:
第一种:
<?php
require('class/class1.php');
require('class/class2.php');
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
$class1=new class1;
}else{
echo "not a girl";
$class2=new class2;
}
在地址栏输入:127.0.0.1/lazy/index.php?sex=0
第二种:
<?php
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
require('class/class1.php');
$class1=new class1;
}else{
echo "not a girl";
require('class/class2.php');
$class2=new class2;
}
在地址栏输入:127.0.0.1/lazy/index.php?sex=0
第三种:
<?php
function my_loader($class){
require('class\\'.$class.'.php');
}
spl_autoload_register('my_loader');
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
$class1=new class1; //first use
}else{
echo "not a girl";
$class2=new class2; //second use
}
当代码执行到"first use"或者"second use"时,发现不存在该类,就会触发spl_autoload_register()函数
$class参数就为class1或者class2,这样就可以动态的引入该类
类的映射表机制加载:
在controllers/HelloController.php中:
\YII::$classMap['app\models\Order']="D:\www\basic\models\Order.php';
$order=new Order;
当new Order时,就回去在类的映射表中去超找,找到其绝对路劲,加载该类
一般当访问入口文件时,就会去创建一个应用实例,应用实例回去加载相应的组件components/session components/request componest/response等组件
所以直接在controllers中写$session=\YII::$app->session;也是ok的
缓存组件:
//获取缓存组件
$cache=\YII::$app->cache;
//往缓存当中写数据
$cache->add('key1','hello world1');
$cache->add('key2','hello world2');
//有效期设置
$cache->add('key','hello world',15); //缓存15秒
//修改数据
$cache->set('key1','hello world3');
//删除数据
$cache->delete('key1');
//清空数据
$cache->flush();
//读缓存
$data=$cache->get('key1');
var_dump($data);
文件依赖:
$cache=\YII::$app->cache;
$dependency=new \yii\caching\FileDependency(['filename'=>'hw.txt']); //该文本文件和入口文件在同一个目录下
$cache->add('file_key','hello world!',3000,$dependency);//缓存在文件5分钟,当文件的修改时间或者有改动该缓存就会失效
var_dump($cache->get('file_key'));
表达式依赖
$dependency=new \yii\cacheing\ExpressionDependency(
['expression'=>'\YII::$app->request->get("name")']
);
$cache->add('expression_key','hello world!',3000,$dependency);
var_dump($cache->get('expression_key'));
请求url为:127.0.0.1/basic/web/index.php?r=hello/index&name=zhangsan
第一次请求将name的值写入缓存,当第二次请求name的值发生改变时,缓存失效
DB依赖
$dependency=new \yii\cacheing\DbDependency(
['sql'=>'select count(*) from yii.order']
);
$cache->add('db_key','hello world',3000,$dependency);
var_dump($cache->get('db_key'));
当数据库中的表order的记录数发生变化时,该缓存就会失效
块缓存
在视图文件中,写入如下
<?php if($this->beginCache('cache_div')) { ?>
<div id='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); }?>
<div id='no_div_cache'>
<div>这里不会被缓存</div>
</div>
在浏览器中访问,id=caceh_div的块被缓存起来,当改变该块内的内容时,页面不会发生改变
设置缓存时间 (单位为秒)
<?php $duration=15; ?>
<?php if($this->beginCache('cache_div',['duration'=>$duration])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
时间过期缓存失效
//缓存依赖
<?php
$dependency=[
'class'=> 'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
];
?>
<?php if($this->beginCache('cache_div',['dependency'=>$dependency])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
所依赖的文件被修改,文件失效
缓存开关
<?php $enabled=false; ?>
<?php if($this->beginCache('cache_div',['enabled'=>$enabled])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
是否开启缓存
嵌套缓存
在缓存组件内部还有一个缓存组件
<?php if($this->beginCache('cache_div',['duration'=>20])){ ?>
<div di='cache_outer_div'>
<div>这里是外层,待会儿会被缓存</div>
<?php if($this->beginCache('cache_inner_div',['duration'=>2])){ ?>
<div id='cache_inner_div'>
这里是内层,待会儿会被缓存
</div>
<?php $this->endCache(); ?>
</div>
<?php $this->endCache(); } ?>
由于里面和外面的缓存时间不一致,以外面的为准,从外面整个div开始里面所有的都会被缓存
页面缓存
在控制器文件中,进行页面缓存的设置
引入方法behaviors
public function behaviors(){
return [
[
'class'=>'yii\filters\PageCache'
]
];
}
public function actionIndex(){
return $this->render('index'); //将缓存整个页面
}
将页面缓存到文件
public function behaviors(){
return [
[
'class'=>'\yii\filters\PageCahce',
'duration'=>1000,
'dependency'=>[
'class'=>'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
]
]
];
}
public function actionIndex(){
return $this->render('index'); //将缓存整个页面
}
缓存指定页面
public function behaviors(){
return [
[
'class'=>'\yii\filters\PageCahce',
'duration'=>1000,
'only'=>['index'], //将缓存index方法下渲染的模板数据
'dependency'=>[
'class'=>'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
]
]
];
}
public function actionIndex(){
echo 3;
}
public function actionTest(){
echo 4;
}
HTTP缓存
http报文就是浏览器和服务器间通信时发送及响应的数据块
报文包含两部分:
1、包含属性的首部(header)----附加信息(cookie,缓存信息等)与缓存相关的规则信息,均包含在header中
2、包含数据的主体部分(body)----HTTP请求真正想要传输的部分
客户端向服务器发送一个请求,服务器会解析该请求,返回相应的数据。
在返回数据时在http头部附加一个字段last_modified,并将该数据缓存到浏览器。下一次请求该数据块时,就会附带该字段
服务器就会比对该字段,如果该字段和服务器该块数据一致,就不会给客户端返回该块数据,而是使用浏览器端缓存的数据
但是,当服务器端该块数据的修改时间发生变化时,但是数据没有改变时,这个方案就存在欠缺了,于是引进etag标签,该标签
对该块数据的内容进行标注,(ps:last-modified对该块数据的修改时间进行标记) 如果last-modeified改变了,则进行etag
的验证,如果etag没有发生变化,则使用浏览器端的缓存,否则服务器端重新发送该数据块给客户端。(注意查看HTTP报文response字段)
在controller下,编写behaviors方法
public function behaviors(){
return [
[
'class'=>'yii\filters\HttpCache',
'lastModified'=>function(){
return 1423567803;
},
'etagSeed'=>function(){
return 'etagseed2';
}
]
];
}
public function actionIndex(){
return $this->renderPartial('index');
}
以一个文件为例子浅析http
public function behaviors(){
return [
[
'class'=>'yii\filters\HttpCache',
'lastModified'=>function(){
return filetime('hw.txt');
},
'etagSeed'=>function(){
$fp=fopen('hw.txt','r');
$title=fgets($fp);
fclose($fp);
return $title;
}
]
];
}
public function actionIndex(){
$content=file_get_contents('hw.txt');
return $this->renderPartial('index',['new'=>$content]);
}
在controller中使用return $this->renderPartial('index');//表示渲染index视图
在视图文件index.php中写入<h1>hello index</h1>
在视图文件about.php中写入<h1>hello about</h1>
在视图文件index.php中调用视图文件about.php 添加如下代码
<?php echo $this->render('about',array('v_hello_str'=>'hello world'));?>
在about视图文件中添加入下代码:
<h1><?=$v_hello_str; ?></h1>
在浏览器调用index视图就可以实现视图调用视图
布局文件:
将index.php视图文件和about.php视图文件的公共部分删除放入到layout.php(默认渲染)中
在controller中使用return $this->render('index'); //render将视图文件的内容放入到$content中
还可以添加一个属性指定布局文件 public $layout='common'; 将使用layout/common.php进行渲染
数据块:
在视图文件定义数据块,可以覆盖布局文件相应的块
在index.php视图文件中定义如下代码:
<?php $this->beginBlock('block1'); ?>
<h1>index</h1>
<?php $this->endBlock(); ?>
在布局文件相应的地方写入如下代码进行调用:
<?=$this->blocks['block1']; ?>
也可以进行判断:
<?php if(isset($this->blocks['block1'])): ?>
<?=$this->blocks['block1']; ?>
<?php else: ?>
<h1>hello Common</h1>
<?php endif; ?>
命名空间:
顶级的类只需要在类名前加入一个反斜线,便可以new一个对象。
其他类使用use关键字,也可以区别名,例如:
use a\b\c\Apple;
use d\e\f\Apple as BApple;
$a=new Apple();
$b=new BApple();
$c=new \Apple();
响应:
$res= \YII::$app->response;
$res->statusCode='404'; //设置状态码
$res->headers->add('pragma','no-cache'); //设置http头
$res->headers->set('pragma','max-age=5');
$res->headers->remove('pragma');
//跳转
$res->header->add('location','http://www.baidu.com');
$this->redirect('http://www.baidu.com',302);
//文件下载
$res->headers->addd('content-disposition','attachment; filename="a.jpg"');
$res->sendFile('/robots.txt'); //找入口文件路劲下的文件
session:
$session=\YII::$app->session;
$session->open();
if($session->isActive){
echo 'session is active';
}
$session->set('user','张三');
echo $session->get('user');
$session->remove('user');
$session['user']='张三';
echo $session['user'];
unset($session['user']);
cookie:
$cookies=\YII::$app->response->cookies;
$cookie_data=array('name'=>'user','value'=>'zhangsi');
$cookies->add(new Cookie($cookie_data));
$cookies->remove('is');
$cookies=\YII::$app->request->cookies;
echo $cookies->getValue('user',20);
renderPartial渲染一个视图并传递参数
在controllers中:$hello_str="Hello God!";
//创建一个数组
$data=array();
//把需要传递给视图的数据,放到数组当中
$data['view_hello_str']=$hello_str;
return $this->renderPartial('index',$data);
在视图中使用如下方法输出
<?=$view_hello_str;?>
多个数据可以使用:<?=$view_test_arr[0];?>数组形式输出
//过滤js代码,但是可以当字符串输出
<?=Html::encode($view_hello_str);?>
//过滤js,没有js代码的输出
<?=HtmlPurifier::process($view_hello_str);?>
查询数据:
应当在config/db.php 配置数据库
在models下建立一个与表名一样的.php文件
在controllers中如下:
$sql="select * from test where id=1";
$result=Test::findBySql($sql)->all();
print_r($result);
//$id='1 or 1=1';
$sql='select * form test where id=:id";
$result=Test::findBySql($sql,array(':id'=>1))->all();
$result=Test::findBySql($sql,array(':id'=>'1 or 1=1'))->all();
print_r($result);
//id=1
$results=Test::find()->where(['id'=>1])->all();
//id>0
$results=Test::find()->where(['>','id',0])->all();
//id>=1 并且id<=2
$results=Test::find()->where(['between','id',1,2])->all();
//title like "%title%"
$results=Test::find()->where(['like','title','title'])->all();
//查询结果转换成数组,对象比较占内存
$resulr=Test::find()->where([''between','id',1,2])->asArray()->all();
//批量查询
foreach(Test::find()->batch(1) as $test){
print_r(count($test));
}
//删除数据
$results=Test::find()->where(['id'=>1])->all();
$results[0]->delete();
Test::deleteAll('id>:id',array(':id'=>0));
增加数据
$test=new Test();
$test->id=3;
$test->title='title3';
$test->validate(); //进行规则验证
if($test->hasErrors()){
echo 'data is error';
}
$test->save();
//修改数据
$test-Test::find()->where(['id'=>4])->one();
$test->title='title4';
$test->save();
//关联查询
models/Customer.php
public function getOrders(){
$orders=$this->hasMany(Order::className,['customer_id'=>'id'])->asArray()->all();
return $orders;
}
models/Order.php
public function getCustomer(){
return $this->hasOne(Customer::className(),['id'=>'customer_id')->asArray();
}
controllers/HelloControllers.php
public function actionIndex(){
//根据顾客信息查询她/他的订单信息
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//customer_id在app\models\Order表中,ID在Customer表中
$orders=$customer->hasMany('app\models\Order',['customer_id'=>'id'])->asArray()->all();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//$orders=$customer->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
$orders=$customer->getOrders();
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->orders; //调用魔术方法__get,之后调用getOrders()(自己实现),之后再查询结果后面加调用all()
//根据订单查询顾客的信息
$order=Order::find()->where(['id'=>1])->one();
$customer=$order->customer;
print_r($customer);
//关联查询的多次查询(N+1次)
$customers=Customer::find()->where('orders')->all(); //select * from customer;
foreach($customers as $customer){
$orders=$customer->orders; //select * from order where customer_id =....
}
//关联查询的多次查询(2次)
//select * from customer;
//select * from order where customer_in in ....;
$customers=Customer::find()->with('order')->all();
foreach($customers as $customer){
$orders=$customer->orders;
}
}
类的自动加载:
存在class/class1.php class/class2.php 和index.php
在index.php中:
第一种:
<?php
require('class/class1.php');
require('class/class2.php');
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
$class1=new class1;
}else{
echo "not a girl";
$class2=new class2;
}
在地址栏输入:127.0.0.1/lazy/index.php?sex=0
第二种:
<?php
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
require('class/class1.php');
$class1=new class1;
}else{
echo "not a girl";
require('class/class2.php');
$class2=new class2;
}
在地址栏输入:127.0.0.1/lazy/index.php?sex=0
第三种:
<?php
function my_loader($class){
require('class\\'.$class.'.php');
}
spl_autoload_register('my_loader');
$is_girl=$_GET['sex']==0 ? true : false;
if($is_girl){
echo "this is a girl";
$class1=new class1; //first use
}else{
echo "not a girl";
$class2=new class2; //second use
}
当代码执行到"first use"或者"second use"时,发现不存在该类,就会触发spl_autoload_register()函数
$class参数就为class1或者class2,这样就可以动态的引入该类
类的映射表机制加载:
在controllers/HelloController.php中:
\YII::$classMap['app\models\Order']="D:\www\basic\models\Order.php';
$order=new Order;
当new Order时,就回去在类的映射表中去超找,找到其绝对路劲,加载该类
一般当访问入口文件时,就会去创建一个应用实例,应用实例回去加载相应的组件components/session components/request componest/response等组件
所以直接在controllers中写$session=\YII::$app->session;也是ok的
缓存组件:
//获取缓存组件
$cache=\YII::$app->cache;
//往缓存当中写数据
$cache->add('key1','hello world1');
$cache->add('key2','hello world2');
//有效期设置
$cache->add('key','hello world',15); //缓存15秒
//修改数据
$cache->set('key1','hello world3');
//删除数据
$cache->delete('key1');
//清空数据
$cache->flush();
//读缓存
$data=$cache->get('key1');
var_dump($data);
文件依赖:
$cache=\YII::$app->cache;
$dependency=new \yii\caching\FileDependency(['filename'=>'hw.txt']); //该文本文件和入口文件在同一个目录下
$cache->add('file_key','hello world!',3000,$dependency);//缓存在文件5分钟,当文件的修改时间或者有改动该缓存就会失效
var_dump($cache->get('file_key'));
表达式依赖
$dependency=new \yii\cacheing\ExpressionDependency(
['expression'=>'\YII::$app->request->get("name")']
);
$cache->add('expression_key','hello world!',3000,$dependency);
var_dump($cache->get('expression_key'));
请求url为:127.0.0.1/basic/web/index.php?r=hello/index&name=zhangsan
第一次请求将name的值写入缓存,当第二次请求name的值发生改变时,缓存失效
DB依赖
$dependency=new \yii\cacheing\DbDependency(
['sql'=>'select count(*) from yii.order']
);
$cache->add('db_key','hello world',3000,$dependency);
var_dump($cache->get('db_key'));
当数据库中的表order的记录数发生变化时,该缓存就会失效
块缓存
在视图文件中,写入如下
<?php if($this->beginCache('cache_div')) { ?>
<div id='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); }?>
<div id='no_div_cache'>
<div>这里不会被缓存</div>
</div>
在浏览器中访问,id=caceh_div的块被缓存起来,当改变该块内的内容时,页面不会发生改变
设置缓存时间 (单位为秒)
<?php $duration=15; ?>
<?php if($this->beginCache('cache_div',['duration'=>$duration])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
时间过期缓存失效
//缓存依赖
<?php
$dependency=[
'class'=> 'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
];
?>
<?php if($this->beginCache('cache_div',['dependency'=>$dependency])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
所依赖的文件被修改,文件失效
缓存开关
<?php $enabled=false; ?>
<?php if($this->beginCache('cache_div',['enabled'=>$enabled])){ ?>
<div di='cache_div'>
<div>这里待会儿会被缓存</div>
</div>
<?php $this->endCache(); } ?>
是否开启缓存
嵌套缓存
在缓存组件内部还有一个缓存组件
<?php if($this->beginCache('cache_div',['duration'=>20])){ ?>
<div di='cache_outer_div'>
<div>这里是外层,待会儿会被缓存</div>
<?php if($this->beginCache('cache_inner_div',['duration'=>2])){ ?>
<div id='cache_inner_div'>
这里是内层,待会儿会被缓存
</div>
<?php $this->endCache(); ?>
</div>
<?php $this->endCache(); } ?>
由于里面和外面的缓存时间不一致,以外面的为准,从外面整个div开始里面所有的都会被缓存
页面缓存
在控制器文件中,进行页面缓存的设置
引入方法behaviors
public function behaviors(){
return [
[
'class'=>'yii\filters\PageCache'
]
];
}
public function actionIndex(){
return $this->render('index'); //将缓存整个页面
}
将页面缓存到文件
public function behaviors(){
return [
[
'class'=>'\yii\filters\PageCahce',
'duration'=>1000,
'dependency'=>[
'class'=>'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
]
]
];
}
public function actionIndex(){
return $this->render('index'); //将缓存整个页面
}
缓存指定页面
public function behaviors(){
return [
[
'class'=>'\yii\filters\PageCahce',
'duration'=>1000,
'only'=>['index'], //将缓存index方法下渲染的模板数据
'dependency'=>[
'class'=>'yii\caching\FileDependency',
'fileNmae'=>'hw.txt'
]
]
];
}
public function actionIndex(){
echo 3;
}
public function actionTest(){
echo 4;
}
HTTP缓存
http报文就是浏览器和服务器间通信时发送及响应的数据块
报文包含两部分:
1、包含属性的首部(header)----附加信息(cookie,缓存信息等)与缓存相关的规则信息,均包含在header中
2、包含数据的主体部分(body)----HTTP请求真正想要传输的部分
客户端向服务器发送一个请求,服务器会解析该请求,返回相应的数据。
在返回数据时在http头部附加一个字段last_modified,并将该数据缓存到浏览器。下一次请求该数据块时,就会附带该字段
服务器就会比对该字段,如果该字段和服务器该块数据一致,就不会给客户端返回该块数据,而是使用浏览器端缓存的数据
但是,当服务器端该块数据的修改时间发生变化时,但是数据没有改变时,这个方案就存在欠缺了,于是引进etag标签,该标签
对该块数据的内容进行标注,(ps:last-modified对该块数据的修改时间进行标记) 如果last-modeified改变了,则进行etag
的验证,如果etag没有发生变化,则使用浏览器端的缓存,否则服务器端重新发送该数据块给客户端。(注意查看HTTP报文response字段)
在controller下,编写behaviors方法
public function behaviors(){
return [
[
'class'=>'yii\filters\HttpCache',
'lastModified'=>function(){
return 1423567803;
},
'etagSeed'=>function(){
return 'etagseed2';
}
]
];
}
public function actionIndex(){
return $this->renderPartial('index');
}
以一个文件为例子浅析http
public function behaviors(){
return [
[
'class'=>'yii\filters\HttpCache',
'lastModified'=>function(){
return filetime('hw.txt');
},
'etagSeed'=>function(){
$fp=fopen('hw.txt','r');
$title=fgets($fp);
fclose($fp);
return $title;
}
]
];
}
public function actionIndex(){
$content=file_get_contents('hw.txt');
return $this->renderPartial('index',['new'=>$content]);
}