1、__autoload()
当编写面向对象的代码时,人们经常习惯于把每一个类放到它自己的源文件中。这样做的好处是可以很轻松地找到类在哪里,而且这样还可以将包含的代码数量最小化,因为你只须引入实际需要的类。
缺陷:你不得不经常包含大量的源文件,而且经常导致包含太多的文件和一个头疼的代码维护问题。
如果你定义一个__autoload()函数(每一个应用只能有一个这样的函数),而且当你访问一个还未存在的类时,它将被调用并且把类的名字作为它的参数,这样就给你一个实时包含类的可能性。如果你成功地包含了该类,你的源代码会继续执行,就像这个类已经定义了一样。如果你没有成功地包含该类,脚本引擎会产生一个类不存在的严重错误。
MyClass.php
<?php class MyClass{ function printHelloWorld(){ print "Hello,Wolrld\n"; } } ?>
general.inc
<?php function __autoload($class_name){ //载入web服务器的根目录下demo/目录种的指定类名 $class_name=strtolower($class_name); //统一将类名转变为小写 require_once($_SERVER['DOCUMENT_ROOT']."/demo/$class_name.class.php"); } ?>
main.php
<?php /** *只要MyClass.php存在于Web服务器的根目录下面的demo/目录中,代码将打印Hello,World */ require_once "general.inc"; $obj =new MyClass(); $obj->printHelloWorld(); ?>
在这个例子中,MyClass.php并没有真正包含于main.php文件中,而是通过将__autoload()函数定义在一个文件中,并在你所有的主脚本文件中包含它,如本例子中的general.inc文件,从而当你需要调用的类时,暗中调用__autoload()函数包含进来,从而可以节省大量的代码而且可以减少维护代码的工作量。
2、spl_autoload_register()
__autoload()可以实现自动加载类,但有一个致命的缺陷,就是整个应用中只能有一个__autoload()函数,如上例子中,类只能存放于web服务器下的demo目录中,类名才会自动被加载。
spl_autoload_register()弥补了函数__auotload()的缺陷,可以将整个应用中定义多个__autoload()函数。
如果在你的程序中已经使用了__autoload()函数,那么__autoload()函数必须显示注册到__autoload()队列中。
为了在框架中实现自动加载类名,通常我们命名类名都以XXX再加上.class.php形式来保存,比如XXXController.class.php来表示XXX的控制器,XXXModel.class.php来表示XXX的模型类。
第一种方法:
<?php /** *使用spl_autoload_resigter实现自动加载 *在MVC框架中,类名通常放置在框架目录中,这些目录与应用程序无关,这些目录是固定的。然后通过file_exists()函数判断类名是否存在,将自动触发spl_autoload_register()函数。 *对于应用下的控制器和模型,都基于应用平台,通过平台分发参数来确定,一旦平台分发参数确定,那么子目录也可以确定。 *这里只简单介绍spl_autoload_register()函数定义和使用 * *自动加载Controller和Model类 *如果是控制器,则从Controller目录加载类 *如果是模型类,则从Model目录记载类 */ function my_autoload($class_name){ //截取类名后10个字符,与Controller比较,如果相等,说明是控制器 if(substr($class_name,strtpos($class_name,-10))=='Controller'){ require_once './Controller/'.$class_name.'.class.php'; }elseif(substr($class_name,strtpos($class_name,-5))=='Model'){ //如果类名后5个字符,与Model比较,如果相等,说明是模型类 require_once './Model/'.$class_name.'.class.php'; } } spl_autoload_register('my_autoload'); ?>
上面这种方法可以演变成匿名函数书写形式:
<?php spl_autoload_register(function($class_name){ if(substr($class_name,-10)=='Controller'){ require_once './Controller/'.$class_name.'.class.php'; }elseif(substr($class_name,-5))=='Model'){ require_once './Model/'.$class_name.'.class.php'; } }); ?>