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 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]);
}





















分享给朋友:
您可能感兴趣的文章:
随机阅读: