-
1.Yii框架里Gii工具的使用(basic/web/index.php?r=gii) 《程序员修炼之道》 对于往往是不可避免的“强加的重复”,我们可以用Code Generator这种模式来解决。 对于某些重复性的代码,比如(namespace app\controllers;)这类代码每写一个控制器都要重新敲一遍,可以通过编写工具来自动生成这类代码。 2.Gii的作用就是帮助我们去生成一些强加性的重复代码。 Gii的首页是怎样打开的?通过在地址栏输入(localhost/basic/web/index.php?r=gii)打开,让r=gii。之前是r=hello,会去访问同名的控制器,那gii为什么没有去访问一个GiiController的文件呢? 主要的原因是:Yii框架里面实际上使用了模块化的思想来进行设计的,也就是说Yii框架里面有很多模块,gii就是其中之一,应用主体app也是其中比较主要的模块。然后所有其他的模块其实都是挂载在应用主体上的。当r=word,应用主体会对r进行处理,看word是一个模块还是一个控制器,如果是模块直接交给模块来处理,如果是控制器,才交给应用主体自己,然后应用主体在它里面找到合适的控制器去使用。 3.另外,每个模块都是有MVC这三个文件夹的,因为会先找模块再去找控制器,所以写了r=gii也不会报错,而是显示了gii的首页。 4.Gii给我们提供了哪些工具:1.Model Generator(数据模型的代码生成器)、2.CRUD Generator(增删改查的代码生成器)、3.Controller Generator(控制器的代码生成器)、4.Form Generator(表单的代码生成器)、5.Moudle Generator(模块的代码生成器)、6.Extension Generator(扩展的代码生成器)查看全部
-
HelloController.php public function behaviors(){ } public function actionIndex(){ //http缓存实例:在actionIndex操作显示一个文件的内容时,使用lastModified和etagSeed对程序进行优化。 //通过file_get_contents(filename)这个方法去读取文件里的内容,再放到$content变量中,把$content的内容传递到httpcache视图当中去显示。 $content = file_get_contents('http.txt'); //使用renderPartial的第二个参数(数组['keyname'=>'value'])把$content里的新闻内容传递到视图中。 return $this->renderPartial('httpcache',['new'=>$content]); } basic/views/hello/httpcache.php <!-- http缓存实例:通过renderPartial的第二个参数里的key(转化为变量名)把$content里的内容显示出来。 --> <div> <div><?=$new;?></div> </div> http.txt 夏洛特烦恼 ————开心麻花 昔日校花秋雅的婚礼正在隆重举行,学生时代暗恋秋雅的夏洛(沈腾 饰)看着周围事业成功的老同学,心中泛起酸味,借着七分醉意大闹婚礼现场,甚至惹得妻子马冬梅(马丽 饰)现场发飙,而他发泄过后却在马桶上睡着了。梦里他重回校园,追求到他心爱的女孩、让失望的母亲重展笑颜、甚至成为无所不能的流行乐坛巨星…… 醉生梦死中,他发现身边人都在利用自己,只有马冬梅是最值得珍惜。————开心麻花查看全部
-
public function behaviors(){ //4.每次刷新L都会向F发送请求,F都会运行actionIndex操作,从而每次通过file_get_contents读取http.txt文件里的内容,即使文件里的内容没有经过修改也会读取,如果这个文件内容很多,那么读起来也是比较费时的,所以需要lastModified和etagSeed对读取进行优化。 return [ [ 'class'=>'yii\filters\HttpCache', 'lastModified'=>function(){ //4.通过filemtime(filename)方法判断http.txt的修改日期有没有发生变化。这个方法会返回文件上一次的修改时间(时间戳)。 return filemtime('http.txt');//使用return方式把这个时间戳告诉L,等L第2次发送请求过来时,比对L和这边的时间戳是否一样,一样则让L使用缓存。 }, //4.如果F真的把http.txt里的内容修改了,还可以通过etagSeed判断修改后的内容和L里的内容是否一样,因为文件内容有可能改完又改回原样,内容没变化,但修改时间却改变了。 'etagSeed'=>function(){ //4.怎么判断文件新闻内容(分为标题和内容)有没变化?判断标题有没变化,如果没就简单粗暴认为文件内容没有发生变化。 $fp = fopen('http.txt','r');//以读的方式打开http.txt文件,打开之后会返回文件的句柄,把它保存到$fp变量中。 $title = fgets($fp);//通过fgets方式读取文件的第一行,保存到$title变量中:fgets需要2个参数,不写第2个参数表示开始从头读它的第一行。 fclose($fp);//通过fclose方式关闭文件 //把新闻标题$title作为etagSeed的种子,经过一定的转换后再传递给L,L下一次发送请求来时,如果lastModified发现filemtime发生变化,就让etagSeed判断$title有没发生变化。 return $title;//如果$title没发生变化,则简单认为http.txt文件内容没发生变化,那就不会执行actionIndex操作,file_get_contents就不会执行。 } ] ]; }查看全部
-
HelloController.php //Yii高效篇————HTTP缓存的使用 public function behaviors(){ //http缓存之etag //3.etagSeed同样也可判断F和L两边的数据是否一样。一样则F返回304,让L使用缓存数据。etag的工作方式和lastModified一样。 return [ [ 'class'=>'yii\filters\HttpCache', 'lastModified'=>function(){ //return 1432817565;//返回一串整数(时间戳) return 1432817566;//修改了时间信息,httpcache里修改的内容才会被显示出来。 }, 'etagSeed'=>function(){ return 'etagseed2';//返回字符串 } ] ]; } public function behaviors(){ return $this->renderPartial('httpcache'); } basic/views/hello/httpcache.php <div> <div>this is a view of httpcache!</div> </div>查看全部
-
HelloController.php public function behaviors(){ //http缓存之lastModified //2.即使F的数据@修改了,和L的缓存不一样了,F还是淡定的返回了304状态码。F凭什么认定两个数据一样,判断的依据是什么?实际上是根据lastModified这个配置项来判断的。 //当F发送响应数据给L时,HttpCache会把lastModified所得到的整数转化为时间相关的信息F_lm塞到http响应头中,然后L会得到这个时间相关的信息并存储为L_lm。当L下一次访问F时会带上L_lm,F会比对L_lm和和F_lm是否是同一个时间,如果是同一时间F就认为两边数据一样没必要再发新数据给L了。这时候F会把304状态码发送给L。 //只有当F修改了时间信息,F和L的时间信息不一样了,再刷新L,L才会把httpcache最新的结果获取得到,F返回的响应数据(会带上新的时间戳转化成的时间信息)的状态码也变成了200(OK),原因是F也认为两边数据不一样了,返回了新的数据。 return [ [ 'class'=>'yii\filters\HttpCache', 'lastModified'=>function(){ //return 1432817565;//返回一串整数(时间戳) return 1432817566;//修改了时间信息,httpcache里修改的内容才会被显示出来。 } ] ]; } public function actionIndex(){ return $this->renderPartial('httpcache'); } basic/views/hello/httpcache.php <div> <div>this is a view of httpcache!233</div> </div>查看全部
-
HelloController.php //Yii高效篇————HTTP缓存的使用 public function behaviors(){ //http缓存之缓存时机 //1.F是怎么告诉L把数据缓存在浏览器本地的呢?HttpCache类决定了L要不要缓存F发送给它的数据。F发送数据给L是是以响应的方式,响应分为响应头和响应体2部分。 //实际上HttpCache在响应发送给L之前,会往响应头存放一些缓存相关的信息(Cache-Control:"public, max-age=3600"),然后L在接收到响应之后会根据缓存相关的信息(Cache-Control)来决定把数据缓存在L这边。 return [ [ 'class'=>'yii\filters\HttpCache', 'lastModified'=>function(){ return 325160641;//返回一个时间戳 } ] ]; } public function actionIndex(){ //Yii高效篇————HTTP缓存的使用 return $this->renderPartial('httpcache'); } basic/views/hello/httpcache.php <!-- Yii高效篇————HTTP缓存的使用 --> <div> <div>this is a view of httpcache!</div> </div>查看全部
-
1.如何证明http缓存是缓存在浏览器这边的?右键审查元素->Network(可以监控捕获L发送给F的请求,F返回给L的响应)。F5刷新,数据@为F返回给L的响应数据。数据@有一个状态码304(Not Modified:未修改)。 L第一次给F发送请求时,F会乖乖生成数据@,把@以响应的方式发送给L,但F在发送@时可以要求L接收到@后把@缓存在L里面。然后L第2次访问F向F要数据时,F会比对L所要数据和@是否一样,一样则返回状态码304,告诉L所要的数据和@一样,直接使用L里的缓存数据,把缓存数据显示在页面当中就ok了。 2.F怎么告诉L接收到数据@后把@给缓存起来? 3.明明修改了F里的数据@,为什么L还是使用缓存的数据显示在页面当中?L使用缓存数据肯定是F返回了304的状态码,也就是说F认为F里的数据@和L的数据是一样的。那么F和L之间数据的对比依据是什么样子的呢?查看全部
-
什么是http缓存? 用矩形L代表浏览器,矩形F代表服务器。 1.当用户到F浏览网站或一个页面时,就会用L给F发送一个请求,然后F就会处理这个请求,处理完之后会把处理的结果作为一个响应返回给L,然后L从这个响应里拿数据,再显示出来,这样用户就可以看到他想看到的页面了。 2.但这时会遇到一个小问题,如果用户从F拿过来的数据不是他想要的数据(比如12306订票页面想订的票没有了),这时用户猛刷新L,那么L就会给F发送很多的请求,实际上F的数据是没有发生变化的,F收到这么多请求后都会照常的处理,但处理的结果没有发生变化,所以处理的结果跟第一次返回出去的数据是一样的。所以这样对F来说,很浪费资源、时间。 3.F想了一个办法,当F第一次把数据(小圆表示)发送给L时,它让L把数据缓存到L里面,也就是把它缓存起来,缓存起来以后如果下一次L发送了请求到了F这边之后,F会对比F这边的数据和L那边的数据是不是一样的(F是如何校验的呢?),如果是一样的那就没必要再把这个数据发送回给L了,就让L使用缓存里的数据就行了。 4.F如何校验F和L的数据是一样的,F就想了一个办法。当F第一次发送数据给L时,会在数据中塞入一个last-modified字段(记录了F这边数据的修改时间),那么L也有了这个字段。那么当L下一次发送请求时,会把这个修改时间也带上,也就是把lm(last-modified字段)发送回给F,F会校验lm和F里的那个数据的修改时间是否是一样的,如果是一样的那么这个数据肯定没有被修改过,那就没必要再发送回给L了,直接告诉L去使用缓存里的数据就行了。 5.另一种校验方式是基于last-modified的小缺陷设计出来的(开发人员把F的数据@改为#,然后又改回@,那么数据@虽然没变化,但它的修改时间改变了。那么L发送过来的lm和数据@的修改时间是对不上的,然后F又把@发送给L,但实际上@没有发生变化,这样也会造成一些问题)。所以F想了一个办法,F第一次发送@数据包时,会根据@里的内容生成一个标志etag,通过etag可以大概了解数据包@里的内容。F会把etag和last-modified一起发送给L,那么L下一次访问F时,会传lm和etag。那么F先验证lm(两边数据修改时间是否一样),一样则使用L的缓存;如果不一样,F则验证etag是否一样,如果一样证明@没有被修改,则让L使用缓存查看全部
-
HelloController.php public function behaviors(){ return [ [ 'class'=>'yii\filters\PageCache', //4.也可以对PageCache做一些配置;设置页面缓存的有效时间 'duration'=>1000, //7.1如果不想缓存actionPage操作的结果,只想缓存actionIndex操作的结果。 //'only'=>['index'], //7.2如果此时想缓存actionPage操作的结果,则在only里补上page操作的名字。 'only'=>['index','page'], //5.设置缓存的依赖,依赖于一个文件。一旦这个文件发生变化,PageCache缓存就会失效,actionIndex就会重新被执行。 'dependency'=>[ 'class'=>'yii\caching\FileDependency', 'fileName'=>'hw.txt' ] ] ]; } public function actionPage(){ //echo '这条语句会被PageCache类缓存';//5.PageCache缓存的数据 echo '这条语句要等缓存失效才会被显示';//5.直到duration有效期失效(超过1000秒)或者hw.txt文件的内容被修改,actionIndex再次被执行,这条修改的语句才会被显示 } //6.另外,现在控制器里只有actionIndex操作,如果再定义一个操作actionPage。 public function actionPage(){ //echo '这里是actionPage操作';//6.这里执行的代码产生的结果同样会被PageCache缓存起来 //echo '这里不会被PageCache缓存,修改内容会即时显示233';//7.1因为设置了'only'=>['index'],所以actionPage操作的结果不会被缓存。 echo '这里会被PageCache缓存233';//7.2因为设置了'only'=>['index','page'],所以actionPage操作的结果会被缓存,修改后还是会显示缓存的内容,除非缓存失效。 }查看全部
-
HelloController.php public function behaviors(){ //2.那么就可以使用在这个behaviors方法里返回的值(返回一个数组,在数组里进行一些配置项)去先告诉Yii框架待会有请求去访问actionIndex操作时,可以把这个操作的结果缓存到一个页面缓存当中。 return [ //3.怎样告诉Yii框架使用页面缓存呢?在这个数组里再去定义一个小的数组。在小数组里告诉Yii框架去使用一个页面缓存的类PageCache(yii\filters) [ 'class'=>'yii\filters\PageCache' ] ]; } public function actionIndex(){ //echo '这里会被PageCache类缓存';//3.PageCache缓存的数据 //echo 'False!浏览器会显示PageCache类缓存的内容';//3.当请求再次来到actionIndex操作,由于上一次echo的结果被缓存起来,会先去behaviors,behaviors告诉Yii框架要使用PageCache,Yii框架了解到PageCache缓存可以用,就到PageCache看看是否有值,如果有值直接传给浏览器。这段echo语句就不会执行了,也就是actionIndex操作压根不会被执行。 $this->render('pagecache');//3.一帮情况下不会在actionIndex里直接通过echo语句去显示什么样的数据,而是更经常的通过$this里的render或renderPartial去显示视图文件,也就是一个页面。同样PageCache会把这个页面的内容给缓存起来,这样就达到了缓存整个页面的目的。 }查看全部
-
HelloController.php //Yii高效篇————页面缓存的使用:整个页面没发生多大变化,使用Yii框架提供的behaviors()方法[关于行为的方法,先于HelloController其它的操作[如actionIndex()]提前执行]缓存整个页面。 public function behaviors(){ //1.有个请求去访问actionIndex操作之前,框架会先去执行behaviors方法,然后再去执行相应的actionIndex操作。 //echo 'behaviors()先执行'.'<br/>'; return []; } public function actionIndex(){ //echo 'actionIndex()后执行';//1.执行完behaviors()里的echo后才会执行这里的echo }查看全部
-
HelloController.php return $this->renderPartial('cache'); basic/views/hello/cache.php <!-- 片段缓存嵌套 --> <!-- 片段缓存的嵌套使用有时会产生一些问题:比如给内外的beginCache都设上一个缓存有效时间duration。 第1次刷新浏览器时,outer和inner里的内容都被缓存了;在20内,如果此时修改了inner里的缓存内容, 再次刷新浏览器,inner里修改后的缓存内容不会被显示,这是因为在20秒有效期内,PHP只解析了outer的缓存(没过期直接抛出缓存数据), 没有去解析inner的缓存(尽管inner缓存的有效期已过并且缓存内容修改了);只有当outer的20秒有效期过期,此时刷新浏览器, inner里被修改过的缓存内容才会被显示出来。--> <?php if($this->beginCache('cache_div',['duration'=>20])){?> <div id='cache_outer_div'> <div>这里是外层,待会会被缓存</div> </div> <?php if($this->beginCache('cache_inner_div',['duration'=>1])){?> <div id='cache_inner_div'> <div>这里是内层,待会会被缓存</div> </div> <?php $this->endCache(); } ?> <?php $this->endCache(); } ?>查看全部
-
return $this->renderPartial('cache'); basic/views/hello/cache.php <!-- 片段缓存设置: --> <?php //1.设置缓存有效时间,失效之后重新读取cache_div里的内容 //$duration = 15; //2.片段缓存依赖设置:定义一个数组,数组里要有一个class去指定使用哪种依赖 /*$dependency = [ 'class' => 'yii\caching\FileDependency', 'fileName' =>'hw.txt' ];*/ //3.缓存开关设置:指定缓存用不用 $enabled = true; ?> <!-- 1.通过beginCache('缓存数据的名字','数组['key'=>'value']')的第2个参数(是一个数组)设置缓存有效时间,duration:有效期 --> <!-- <?//php if($this->beginCache('cache_div',['duration'=>$duration])){?> --> <!-- 2.刷新浏览器,cache_div里的内容被缓存起来。当修改cache_div里的内容时,再次刷新浏览器,显示的还是缓存的内容。只有修改了$dependency对象关联的缓存依赖的文件hw.txt里的内容,再次刷新浏览器cache_div里修改后的内容才会被显示出来。 --> <!-- <?//php if($this->beginCache('cache_div',['dependency'=>$dependency])){?> --> <!-- 3.$enabled为false,那么cache_div不会被缓存,内容是什么就显示什么; $enabled为true,第一次刷新浏览器会把cache_div里的内容缓存起来,之后修改cache_div的内容,刷新浏览器还是会显示之前缓存的cache_div的内容--> <?php if($this->beginCache('cache_div',['enabled'=>$enabled])){?> <div id='cache_div'> <div>这里待会会被缓存233333</div> </div> <?php $this->endCache(); } ?>查看全部
-
HelloController.php //Yii高效篇————片段缓存的使用 //片段缓存介绍(主要负责把前端界面的一些区域[不会经常变动的区域:如京东商品分类]缓存起来[缓存到内存或文件中],下次访问时直接从缓存里把数据拿出来,而不用再从数据库抓取信息,提高了程序的执行效率) return $this->renderPartial('cache');//显示cache视图(basic\views\hello) basic/views/hello/cache.php <!-- 使用视图组件($this)里的beginCache('缓存数据的名字')方法把cache_div给缓存起来;这个方法开启会检查当前有没有缓存,如果没有返回false --> <!-- 如何证明cache_div的代码片段被缓存了呢? 在两个div里都添加上相同的内容。如果cache_div被缓存起来将会使用缓存里的内容,而不会使用修改后的内容。提高了程序的运行效率。 --> <?php if($this->beginCache('cache_div')){?> <div id='cache_div'> <div>这里待会会被缓存(这里是缓存过后添加的)</div> </div> <?php $this->endCache();//结束缓存 } ?> <div id='no_cache_div'> <div>这里不会被缓存(这里是缓存过后添加的)</div> </div>查看全部
-
//数据缓存中依赖关系详解 $cache = \Yii::$app->cache; /*//表达式依赖 //实例化命名空间下的ExpressionDependency类,实例化时传递了expression(表达式)配置项。 $dependency = new \yii\caching\ExpressionDependency( ['expression'=>'\Yii::$app->request->get("name")'] ); //$dependency的用途跟文件依赖类似:当$dependency对象关联的expression表达式中的get方法中的参数改变时,expression_key对应的缓存数据就会失效。 //$cache->add('expression_key','hello expression cache!',3000,$dependency);//存缓存数据之前,在地址栏后面加上&name=wangsicong var_dump($cache->get('expression_key'));*/ //DB依赖(数据库的依赖) //实例化命名空间下的DbDependency类,实例化时传递了sql(sql语句)配置项。 $dependency = new \yii\caching\DbDependency( ['sql'=>'SELECT count(*) FROM yii.order'] ); //$dependency所对应的sql语句执行之后查询出来的结果发生变化,那么db_key对应的缓存数据就会失效。(改变订单表的数据,增加一条数据) //$cache->add('db_key','hello db cache!',3000,$dependency); var_dump($cache->get('db_key'));查看全部
举报
0/150
提交
取消