小白说codeigniter的load->view()视图加载机制 顺带解析一下框架流程(求指正)

   总结:

        当你使用定义一个控制器时, 这个控制器的load成员已经是loader加载器类对象的一个引用 ,控制器加载视图时,也即你用了$this->load->view(' viewName ' , $data)  后, 框架去调用loader装载器对象的view方法 ,这个方法会把你的$data数组使用extract函数把数组元素提取出来,变成变量名和变量值的形式,这也就是为什么你传进去数组,却可以直接把数组元素的名字作为变量使用。那么视图是如何加载的呢,其实就是 内部给你include了一下,就是直接把你的视图文件给包含了进来

 直接就总结,下面的想看的就可以看看如何得出结论的,如果你感兴趣的话:

        初学php框架,一时间难以理解框架复杂功能的实现机制,但是却十分感兴趣,因为只有理解大致发生了什么才有继续学下去的兴趣,否则一直就想背函数似的,根本掌握不了,今天给大家分享下我四处搜集、自己做实验得出的关于ci框架视图加载机制,即load->view的实现。刚开始想着随便找个博客就会得到答案,谁知找半天都找不到,于是就参考着类加载机制以及亲手实验的方法,弄清楚了。

    我当时一直都在费力的弄明白这个load->view(viewName,param)做了什么,而且为什么在视图中调用load->view()传的数组数据时,直接用数组元素的键值就可以了,最开始还以为,框架又向视图发送了post请求,一直都这样理解,后来仔细一想不对:php页面怎么会主动向视图发post请求,后来就越来越迷了,打开搜索引擎搜索ci框架视图实现机制,始终都找不到合适的理解,出现最多的是关于load_class这个函数的定义的理解  以及一些十分浅显的load->view()的用法,也不说咋实现的,于是我自己就想着亲自找出来这个load_view(),找的过程收获不小,对于我这种初学者来说。下面说一下我找的过程以及对视图加载的理解。


1.从入口文件开始

        进入index.php,从开头翻啊翻,定义一系列的常量之类的东西之后在该文件的最后:

require_once BASEPATH.'core/CodeIgniter.php';

包含了框架核心目录的codeigniter.php 下面跳到该文件。


2.查看codeigniter.php

        到了这个codeigniter.php下面,代码挺多的,但是不放弃,这个文件的名字和框架的名字一样 ,可以说是相当重要的吧应该,粗略的看了下,又是一系列的定义与包含文件,一下子就蒙了,后来觉得可能要去找被包含的文件,于是从头开始,不放过任何一个 require_once();    

        第一个被包含的文件是  APPPATH.'config/constants.php'  这个知道一点结合四处刷的博客和亲眼看代码,这个又是一系列的常量定义:

小白说codeigniter的load->view()视图加载机制 顺带解析一下框架流程(求指正)_第1张图片

        继续走,紧挨着又有一个


        这个可以去看看  这个里面市一些公共函数的定义,也可以将自己定义的全局函数放里面,这个函数库很重要,后面会讲到,先不看这个,当时因为觉得函数库而已 ,就是无数个工具,也没注意,继续往下走(忽略一切define):


看到了这个,这个很熟悉,相信大家看视频的时候都用过,把经常用的辅助函数直接写到config数组里面自动加载,不用每次都要调用load函数加载了,  下面继续往下走:

小白说codeigniter的load->view()视图加载机制 顺带解析一下框架流程(求指正)_第2张图片

连着包含了四个,不过我当时就跳了,看了看名字就感觉跟要找的视图加载机制无关,看起来像是一些工具库(我是小白,并不知道是啥,以后再说)继续走


到这了,包含了控制器类的定义,于是这次就进去仔细研究了一下:

把所有的注释注解都去了,复制一下:

class CI_Controller {

	private static $instance;

	public function __construct()
	{
		self::$instance =& $this;
		foreach (is_loaded() as $var => $class)
		{
			$this->$var =& load_class($class);
		}

		$this->load =& load_class('Loader', 'core');    //对   就是这里,load成员是load_class函数返回值的引用
		$this->load->initialize();
		log_message('info', 'Controller Class Initialized');
	}
	public static function &get_instance()
	{
		return self::$instance;
	}

}

猛的一看,这么点代码,为啥功能那么强大!!!可能这就是面向对象吧(2333)于是就结合着各个大佬的博客读了读,这个控制器的定义重要的在于他的构造函数(好吧虽然一看就知道),构造函数定义了自身的load成员是load_class()函数返回值的引用,也就是说控制器load成员是loader类(实例化后的对象)的引用,知道这个就好了下面的褐色字体是对这个函数的解析,可以不看 ,知道功能就好了。

(这个load_class()函数就是我搜索视图机制的时候频繁出现在各个博主博客上面的东西,前面说common.php很重要,因为这个函数就是在common.php里面,代码还挺长,跟功能很搭配,这个函数就是负责加载参数中指明的类,大家可以去看看我作为小白看了半天已经蒙了(被高级代码秀到了),但还是看到了这个函数的最后几句,他把你传进去的类的名字给实例化了


这个就是load_class()函数最后几句,拽来拽去最后这几句还是可以理解的,把你传进去的类查找之后然后给new了一下(实例化),然后返回这个类 实例化之后 的对象,最后通过函数前面的&符号取得对象的引用,)

知道了这些,再看看load成员到底是啥,前面红字标明了load是loader类对象的引用!!我们去看看这个东西到底是啥,答案就在不远了!!

3.谜底揭晓,强大的loader(加载器类)

        这个loader在哪,也没见过在哪包含过,先不管这些了,其实就在system/core文件夹里面,其实很自然,这个也算是框架

一个比较牛逼的东西了,当然是在核心文件夹里面了,下面打开它,嘿嘿,这个可以说是很长了,当然了,我们用啥函数用啥库用啥模型之类的东西全都是用的load.....当然是很重量级的定义了


这个一下就找到了,然后下面全都是关于这个类的定义,是的,  1300多行全都是定义这个类的各种成员,从头开始迅速翻可以见到好多熟悉的身影,比如library()函数、model()函数。。。。。这样单独写是不是很陌生却又很熟悉, 前面说了控制器的load成员是loader类的实例化后的对象的引用,于是实际上是这样写的: $this->load->model();  哈哈哈哈,这样写是不是就明白了。
        loader里面library(),model()········,这样的函数的功能就是加载传进去的东西,所谓加载就是 一系列的判断寻找之后再来一个require_once()..................这样说是不是很明白(噗~~去他的加载什么的)

4.不瞎扯了,找到view的实现

        这这这.....有点失望,就这两行,而且还是因为一行太长被挤出来的两行,这个函数居然上来就return!!!
        仔细看看return的啥,仔细看看,其实就是调用了一个函数之后就 跑路了(心中有句mmp),调用了啥,
调用了$this->_ci_load()函数,给_ci_load()穿了一个数组这个数组中的值就是你调用$this->load->view()是传的各种参数,由于这个函数调用的时候是$this->_ci_load();    所以这个函数还是在这个文件里面(这是因为用的this调用所以是调用自己的成员函数),打开搜索功能输入“_ci_load“直接飞过去(当然飞了好几下):
小白说codeigniter的load->view()视图加载机制 顺带解析一下框架流程(求指正)_第3张图片
        对 , 找到了这个函数,这个函数的声明的确是接受了一个参数$_ci_data  ,再看他后面紧接着的几句,直接上去就 foreach遍历数组,如果对语法熟悉的话,很明显可以看出来这就是利用php的可变变量,把数组中的键值对给变成了局部变量,就是 把数组的键名作为变量的名字,键值作为变量的值, 至此对于我这种萌新来说,这种操作可以说是很骚了(不像话的那种),毕竟对于c类比较拘束的语言,哪想到还有这种奇妙的东西和骚的用法。
        当然,还要继续看下去这还没有解决我的问题:给视图分配的数组数据怎么就能直接那样子用了?  
        继续翻,找呀找 ,挺长的定义,找了一个 extract($this->_ci_cached_vars);        这个就是那个在其他博主那搜的关于为什么就能直接把传到视图的数组数据的键名作为变量名直接用的原因,就是 extract函数, 这个函数的作用是 提取数组的元素,将元素的键名作为变量名,键值作为对应变量名的值。
         事已至此了,总算见到端倪了继续走下去:

            这里include了一下,大家可以去上面看看,上面一系列对$ci_path的拼接,最后成了你的视图的路径(应该是的),最后include了一下,你的视图就被加载了,是以include方式加载的....而且之前也说了你传递的那个数组已经被extract了,可以直接用数组元素的键名作为变量名直接使用了    我觉得到此可以结束了 ,初学php框架,言语不妥,有错误之处请指正。

你可能感兴趣的:(web)