让CodeIgniter自动加载所有自定义类
Jan 31
坨坨胡同儿 CodeIgniter, PHP 4 Comments
此文主要是提出一种让CodeIgniter自动加载所有自定义类的办法,即lazyloading。(只适用于没有带参数的构造函数的类)
先举个例子,如果我在一个controller中想调用某自定义的library,一般来讲需要两步:
1. $this->load->library(“mylib”);
2. $this->mylib->myfunction();
虽然第一步不是每次都要调用,但至少要在使用前初始化一次。当需要的library比较多时,假如再加上需要的model类,那就有点烦人了。所以,我们要做的就是去掉第一步,不管在controller,library还是model中,让codeigniter自动load需要的类,这样我们就能更专注于业务逻辑,而不用考虑载入的问题。
大家都知道,php5中预定义了__get()方法来获取属性,这个方法不是默认存在的,需要我们手工添加到类里面去。我们就利用这个方法来实现自动加载,首先需要在system/library/Controller和Model两个codeigniter文件中加上__get()方法,代码如下:
function __get ($name){ if ($name == "config") return; $var =&wxMagicGet($name); return $var; }
而wxMagicGet方法可以定义在一个你自己的helper文件中,代码如下:
function &wxMagicGet($name){ if ($name == "db"){ $CI = &get_instance(); $CI->load->database(); return $CI->$name; } if (!wxGetLoadingInfo($name, $type, $mpath)) return null; $CI = &get_instance(); if ($type == 1){ $CI->load->library($mpath.$name); } else if ($type == 2){ $CI->load->model($mpath.$name); } else { return null; } return $CI->$name; } function wxGetLoadingInfo($name, &$type, &$mpath){ static $pathmap = array(); $filename = $name; if (strripos($name, ".php") === FALSE){ $filename .= ".php"; } return _find_where($filename, $type, $mpath); } function _find_where($name, &$type, &$mpath){ //find in app model $type = 2; if (_find_where_path($name, APPPATH."models/", $mpath)) { $mpath = substr($mpath, strlen(APPPATH."models/")); return true; } //find in app library $type = 1; if (_find_where_path($name, APPPATH."libraries/", $mpath)) { $mpath = substr($mpath, strlen(APPPATH."libraries/")); return true; } //find in base library $type = 1; if (_find_where_path($name, BASEPATH."libraries/", $mpath)) { $mpath = substr($mpath, strlen(BASEPATH."libraries/")); return true; } return false; } function _find_where_path($name, $path, &$mpath){ if (file_exists($path . $name)){ $mpath = $path; return true; } if (file_exists($path . ucfirst($name1))){ $mpath = $path; return true; } if (file_exists($path . strtoupper($name))){ $mpath = $path; return true; } //更深入的查找所有子目录 $found = false; if ($handle = @opendir($path)) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { $child = $path.$file; if(is_dir($child)) { if (_find_where_path($name, $child . "/", $mpath)){ $found = true; break; } } } } closedir($handle); } return $found; }
好,一个自动查找并加载的helper就写好了,记得将这个helper放到application/config/autoload.php文件中,这样codeigniter在每次运行时会自动初始化它。
以后我们开发时不管在哪都可以直接调用需要的类,不需要先load了。:)
Controller里直接写:$this->classname->function(xxx)就行,
Library里需要先初始化codeigniter资源,如:$this->obj = &get_instance();
之后也可直接写:$this->obj->classname->function(xxx)
关于codeigniter的框架结构及初始化程序流程,可以参考下面两篇文章:
codeigniter是如何实现mvc模式以及单一入口
codeIgniter之优缺点
codeigniter手册请查看官方网站:http://codeigniter.org.cn/user_guide/index.html
Feb 04, 2010 @ 11:38:45
娘啊,你真是强啊,php都研究,我太渺小了
[Reply]
Ting Reply:
February 4th, 2010 at 11:46
哈哈 介四我相公罗夕同学写的啦~~~你莫激动呀
[Reply]
Feb 04, 2010 @ 17:59:06
我刚换了个系统,发现你的页面在ie6下错版.这个问题就要研究下,你是想用户体验升级,还是……
[Reply]
Ting Reply:
February 11th, 2010 at 17:15
恩 这个皮肤是临时从网上下的 等过完年我会自己设计个新的 到时一定会兼容IE6的 呵呵 虽然我不太擅长这个吧 谢谢提醒啊~
[Reply]