require include 一个隐藏的用法:作用域。
最近在研究php底层框架,奇怪的一点。控制器里为什么要把从model里获取的数据 需要$this->assign('items', $items); 这种形式模板文件里才可以调用到这个变量。控制器在获取到数据的时候其实就是普通require把模板文件包含进来,这样模板里里就可以调用控制器上面获取到的变量了。我特地写了简单的测试
新建 x.php文件
<?php $a=3; require('z.php');
新建z.php文件
<?php echo $a;
然后localhost/x.php文件去访问
可以看到输出结果
//3
然后控制器里就不行了,必须要赋值操作模板里才可以。一开始以为是框架里做了什么操作,找遍代码也没找到相关机制,然后就想,是不是类有什么隐藏机制。首先我是把模板文件直接require引用到控制器里,然后发现是可以不赋值就可以在模板里调用变量了,于是定位到加载(包含)模板文件的方法,发现他也没什么特别的啊,也是最终进行包含操作。然后跟以为java的同事在讨论。他说了句,会不会是作用域问题?我说怎么可能,百度一大堆从来都是几个包含的区别(还有对php5是错的说法);没提到作用域啊。然后我就搜了相关资料。还真找到了,但是讲的还是不太理解。于是我就自己就测试了,真的存在作用域的问题。于是我再测试
x.php代码改了下(模仿控制器,把加载的操作写在函数里)
<?php $a=3; function test(){ require('z.php'); } test();
z.php里面还是这个
<?php echo $a;
继续localhost/x.php发现报错了
意思就是没有$a这个变量 区别就出来了,而且跟我在mvc框架里发生一样的效果了。
终于明白作用域区别在这里了,reuiqre在方法里封装的话。方法外面的变量在方法里面引用的文件里是获取不到的。方法里面的变量,在方法外面也是引用不到的(读者自己去试试),引用文件里加载的方法或者类是没有作用域限制的(读者自己试试啊)。
对了,require 和include 在这里都是一样的,所以没特别说明了
顺便看下 我写的相关新区别吧