详解spl_autoload_register()函数以及自动加载不同目录的类

在了解spl_autoload_register()函数之前,先来看另一个函数:__autoload。 

一、__autoload 

这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数。看下面例子:

printit.class.php

class PRINTIT {

 function doPrint() {

  echo 'hello world';

 }

}

?>

 

index.php

例1

function__autoload( $class ) {

 $file = $class . '.class.php'; 

 if ( is_file($file) ) { 

  require_once($file); 

 }

}

 

$obj = newPRINTIT();

$obj->doPrint();

?>

运行index.php后正常输出hello world。在index.php中,由于没有包含printit.class.php,在实例化printit时,自动调用__autoload函数,参数$class的值即为类名printit,此时printit.class.php就被引进来了。 

 

在面向对象中这种方法经常使用,可以避免书写过多的引用文件,同时也使整个系统更加灵活。

 

例2(调用不同目录的类)

function__autoload($_ClassName){

         if(substr($_ClassName,-6)=='Action'){

                   requireROOT_PATH.'/action/'.$_ClassName.'.class.php';

         }elseif(substr($_ClassName,-5)=='Model'){

                   requireROOT_PATH.'/model/'.$_ClassName.'.class.php';         

         }else{

                   requireROOT_PATH.'/includes/'.$_ClassName.'.class.php';

         }

}

?>

注释:

ROOT_PATH:为定义的根目录常量

action目录存放控制类,model目录存放模型类,includes存放其他类

类名严格定义,诸如class IndexAction{}、class ManageModel{}、class Tool{}等

 

二、spl_autoload_register() 

再看spl_autoload_register(),这个函数与__autoload有与曲同工之妙,看个简单的例子: 

例1:

functionloadprint( $class ) {

 $file = $class . '.class.php'; 

 if (is_file($file)) { 

  require_once($file); 

 }

}

 

spl_autoload_register('loadprint' );

 

$obj = newPRINTIT();

$obj->doPrint();

?>

将__autoload换成loadprint函数。但是loadprint不会像__autoload自动触发,这时spl_autoload_register()就起作用了,它告诉PHP碰到没有定义的类就执行loadprint()。

spl_autoload_register()调用静态方法

 

class test {

 public static function loadprint( $class ) {

  $file = $class . '.class.php'; 

  if (is_file($file)) { 

   require_once($file); 

  }

 }

}

 

spl_autoload_register(  array('test','loadprint')  );

//另一种写法:spl_autoload_register(  "test::loadprint"  );

 

$obj = newPRINTIT();

$obj->doPrint();

?>

例2:(调用不同目录的类)

define('PATH_ROOT',realpath(dirname(__FILE__)));  //根目录

define('DS',DIRECTORY_SEPARATOR);//路径分割 win下\ linux下/

define('PATH_CLASS',PATH_ROOT.DS.'includes/class/');

define('PATH_MODEL',PATH_ROOT.DS.'includes/model/');

define('PATH_CONTROL',PATH_ROOT.DS.'includes/control/');

 

spl_autoload_register("cms_autoload_class");

 

functioncms_autoload_class($str_className) {

    $_arr_class= explode("_", strtolower($str_className));

    print_r($_arr_class );

    switch ($_arr_class[0]) {

        case "class":

            require(PATH_CLASS . $_arr_class[1]. ".class.php");

            break;

        case "model":

            if (isset($_arr_class[2])&& !fn_isEmpty($_arr_class[2])) {

                //fn_isEmpty函数最后会解释

                require(PATH_MODEL .$_arr_class[1] . "_" . $_arr_class[2] . ".class.php");

            } else {

                require(PATH_MODEL .$_arr_class[1] . ".class.php");

            }

            break;

        case "control":

            if (isset($_arr_class[3])&& !fn_isEmpty($_arr_class[3])) {

                require(PATH_CONTROL .$_arr_class[1] . DS . $_arr_class[2] . DS . $_arr_class[3] .".class.php");

            } else {

                require(PATH_CONTROL .$_arr_class[1] . DS . $_arr_class[2] . ".class.php");

            }

            break;

    }

}

比如控制类文件的存放目录为includes/control/setup/update.class.php

update.class.php文件中的类名为 CONTROL_SETUP_UPDATE;

不难看出,类名CONTROL_SETUP_UPDATE与目录名和类文件名的.class前缀保持一致

利用$_arr_class = explode("_",strtolower($str_className));对类名参数$str_className进行分割,得到数组$_arr_class =Array ( [0] => control, [1] =>setup, [2] => update ),分割成的数组元素恰好就是目录名以及类文件名.class的前缀,然后对数组元素进行判断,若条件成立则required类文件。

若想向纵深一级的目录进行延伸,比如类文件的存放目录为:

includes/control/setup/manage/update.class.php那么类名为CONTROL_SETUP_MANAGE_UPDATE

分割的数组$_arr_class =Array ( [0] => control, [1] =>setup, [2] => manage, [3] => update)

若想向根目录下的五级目录进行延伸,则需要修改程序,得到$_arr_class[4]进行条件判断。


知识扩展:fn_isEmpty()函数

PHP中判断变量为空的几种方法小结

1. isset功能:判断变量是否被初始化

说明:它并不会判断变量是否为空,并且可以用来判断数组中元素是否被定义过

if (!isset($b))echo '$b 未被初始化' . "";

 

2. empty功能:检测变量是否为"空"

说明:任何一个未初始化的变量、值为 0 或 false 或 空字符串"" 或 null的变量、空数组、没有任何属性的对象,都将判断为empty==true

注意1:未初始化的变量也能被empty检测为"空"

 

functionfn_isEmpty($data) {

    if (!isset($data)) {

    returntrue;

    }

         if ($data === null) {

                   return true;

         }

         if (is_array($data) ||is_object($data)) {

    if(empty($data)) {

               returntrue;

    }

         } else {

    if(empty($data) || trim($data) === "") {

               returntrue;

    }

         }

 

         return false;

}

你可能感兴趣的:(php)