牛骨文教育服务平台(让学习变的简单)
博文笔记

yii入门

创建时间:2017-12-15 投稿人: 浏览次数:228
视图调用视图:
在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]);
}





















声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。