大凡编写过PHP代码的同志,可能都对文件包含命令include、include_once、require、require_once再熟悉不过了。虽然这些命令对于我们重复使用相同代码起到了重要的作用,但是随着被包含文件的增多以及被包含文件之间的互包含,导致整个PHP程序的包含关系也错综复杂起来。而且还有一个非常低效的问题,我们每写一个PHP页面可能都要先手工写代码把要用到的外部公用文件一一包含进来,而且一旦我们的项目变得庞大起来,修改这个包含文件的引用将成为一个令人头疼的问题,因为我们要先知道哪里引用了什么外部文件,我们才可以去修改。
幸运的是,随着PHP5的发布,来了一个新函数__autoload,它的入口参数是未被定义的类名称。如果我们在自己的代码里声明了这个函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。说到这里大家应该能想到了,我们可以利用此新特性,再加上采用面向对象的编程方式,把我们需要引用的外部公共代码都封装到一个个的类里面,存储到与类名相同的文件里,到该自动装载函数被触发时,我们就可以直接包含一下与类同名的PHP文件,就可以实现外部文件的动态载入了。这样一来我们在编写代码时就不需要提前包含外部文件了,而且还实现了面向对象的编程模式,一个页面要引入新类只需要直接实例化该类即可,PHP会按照__autoload的定义自动去调用我们的外部文件。修改和扩展都很方便,只要我们把类定义和维护好就可以了。而且即便是多个类之间互相调用和实例化,也无需先包含引入了,只要主代码里有__autoload函数声明并且类定义文件的存储严格按照规则处理,那么类与类之间的互相调用和实例化也都会自动完成,由此我们便可以彻底摆脱原来那种繁琐和低效的外部文件包含方式了。
下面我给大家提供一段简单的示例代码,只要自己定义好外部类文件的命名规则和存放规则,就可以方便的使用这种完全自动化的外部文件包含方式了。
1 <?php
2 function __autoload($class_name) {
3 if(file_exists('inc/'.$class_name.'.php'))
4 {
5 //这里先检查一下类定义文件是否存在
6 //示例文件存放规则是inc目录下以类名为主文件名的PHP文件。
7 require('inc/'.$class_name.'.php'));
8 }
9 else
10 {
11 die('类['.$class_name.']定义文件不存在!');
12 }
13 }
14
15 //下面演示用法,当试图初始化未定义的demo类时,__autoload被调用了。
16 //__autoload会先检查inc/demo.php是否存在,存在则直接包含此文件,调入demo类的定义
17 $demotest=new demo();
18 //成功动态实例化demo类之后调用say方法,会输出“hello,world!”。
19 $demotest->say();
20 ?>
21
22 //下面是inc/demo.php的类定义示例
23 <?php
24 class demo {
25 public function say(){
26 echo "hello,world!";
27 }
28 }
29 ?>