yii入门
视图调用视图:
在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 acApple;
use defApple 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在appmodelsOrder表中,ID在Customer表中
$orders=$customer->hasMany("appmodelsOrder",["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["appmodelsOrder"]="D:wwwasicmodelsOrder.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 yiicachingFileDependency(["filename"=>"hw.txt"]); //该文本文件和入口文件在同一个目录下
$cache->add("file_key","hello world!",3000,$dependency);//缓存在文件5分钟,当文件的修改时间或者有改动该缓存就会失效
var_dump($cache->get("file_key"));
表达式依赖
$dependency=new yiicacheingExpressionDependency(
["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 yiicacheingDbDependency(
["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"=> "yiicachingFileDependency",
"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"=>"yiifiltersPageCache"
]
];
}
public function actionIndex(){
return $this->render("index"); //将缓存整个页面
}
将页面缓存到文件
public function behaviors(){
return [
[
"class"=>"yiifiltersPageCahce",
"duration"=>1000,
"dependency"=>[
"class"=>"yiicachingFileDependency",
"fileNmae"=>"hw.txt"
]
]
];
}
public function actionIndex(){
return $this->render("index"); //将缓存整个页面
}
缓存指定页面
public function behaviors(){
return [
[
"class"=>"yiifiltersPageCahce",
"duration"=>1000,
"only"=>["index"], //将缓存index方法下渲染的模板数据
"dependency"=>[
"class"=>"yiicachingFileDependency",
"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"=>"yiifiltersHttpCache",
"lastModified"=>function(){
return 1423567803;
},
"etagSeed"=>function(){
return "etagseed2";
}
]
];
}
public function actionIndex(){
return $this->renderPartial("index");
}
以一个文件为例子浅析http
public function behaviors(){
return [
[
"class"=>"yiifiltersHttpCache",
"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 acApple;
use defApple 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在appmodelsOrder表中,ID在Customer表中
$orders=$customer->hasMany("appmodelsOrder",["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["appmodelsOrder"]="D:wwwasicmodelsOrder.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 yiicachingFileDependency(["filename"=>"hw.txt"]); //该文本文件和入口文件在同一个目录下
$cache->add("file_key","hello world!",3000,$dependency);//缓存在文件5分钟,当文件的修改时间或者有改动该缓存就会失效
var_dump($cache->get("file_key"));
表达式依赖
$dependency=new yiicacheingExpressionDependency(
["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 yiicacheingDbDependency(
["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"=> "yiicachingFileDependency",
"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"=>"yiifiltersPageCache"
]
];
}
public function actionIndex(){
return $this->render("index"); //将缓存整个页面
}
将页面缓存到文件
public function behaviors(){
return [
[
"class"=>"yiifiltersPageCahce",
"duration"=>1000,
"dependency"=>[
"class"=>"yiicachingFileDependency",
"fileNmae"=>"hw.txt"
]
]
];
}
public function actionIndex(){
return $this->render("index"); //将缓存整个页面
}
缓存指定页面
public function behaviors(){
return [
[
"class"=>"yiifiltersPageCahce",
"duration"=>1000,
"only"=>["index"], //将缓存index方法下渲染的模板数据
"dependency"=>[
"class"=>"yiicachingFileDependency",
"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"=>"yiifiltersHttpCache",
"lastModified"=>function(){
return 1423567803;
},
"etagSeed"=>function(){
return "etagseed2";
}
]
];
}
public function actionIndex(){
return $this->renderPartial("index");
}
以一个文件为例子浅析http
public function behaviors(){
return [
[
"class"=>"yiifiltersHttpCache",
"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]);
}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。