samson

 

php的spl_autoload_register与zend framework的Zend_Loader_Autoloader

初初使用php的时候,引用其他类,都是首先获取类的局对路径,然后通过require_once导入。

那么在child继承parents之前,先导入parents.php

<?php
require_once realpath(dirname(dirname(__FILE__)).'/PParent.php');
class PSon extends PParent
{
function __construct(){

}
}

这样做,对于类结构简单的情况,发现不出来问题(由于当初需要速成php,完成外接的项目,所以就这样做了)

当一个php文件中需要引用的类非常多的时候,而且每次编译的时候,用不了几个类,还用上述的方法,就会导致大部分的文件导入时多余的,所以php的autoload功能(动态加载php文件)就应运而生了。

今天刚学习了这个,现在记录一下。由于我做项目用的是zend_framework,所以同时分析了zend_framework中封装的zend_loader_autoloader的实现。

首先是php5的API----》spl_autoload_register(使用于(PHP 5 >= 5.1.2))

使用的步骤如下:

  1、定义autoload方法(方法名自定义就可以);

  2、用spl_autoload_register注册autoload方法(可以注册多个autoload方法);

  3、使用需要的类(注册autoload方法之后,调用类的时候,会自动按照autoload方法的注册顺序进行load,如果load成功,那么停止执行下一个autoload方法,否则一直到所有autoload方法执行完为止)

sample:

文件路径:

代码:

<?php
class PParent
{
function __construct(){

}
}
<?php
class PSon extends PParent
{
function __construct(){

}
}
<?php
class PDaughter extends PParent
{
function __construct(){

}
}

<?php
global $fileDir;
$fileDir = dirname(__FILE__);

class autoloader
{
public static function parentLoad($class)
{
global $fileDir;
$classDir = realpath($fileDir . './model/' . $class . '.php'); //获得类的路径
if (file_exists($classDir))
{
require_once $classDir;
return true;
}
else {
return false;
}
}
public static function childLoad($class)
{
global $fileDir;
$classDir = realpath($fileDir . './model/child/' . $class . '.php');//获得类的路径
if (file_exists($classDir))
{
require_once $classDir;
return true;
}
else {
return false;
}
}
}

spl_autoload_register(
'autoloader::parentLoad'); //注册自动加载的方法
spl_autoload_register('autoloader::childLoad');

$par = new PParent();//使用类,前面没有显示的调用Model_PParent哦
$child = new PSon();
$daughter = new PDaughter();

zend framework对php5的autoload进行了封装,其实是对类的命名进行了规范,并实现了对应的autoload方法

现在按照zend_loader_autoloader的规范,对上面的程序进行改造。

步骤:

1、将zend framework的library导入项目(等会说导到哪个目录);

2、改类名,如A/B/C.php,则类名改成A_B_C;

3、获取zend_loader_autoloader单例,并设置namespace;

4、使用需要的类;

项目路径:

代码:

<?php
class Model_Child_PDaughter extends Model_PParent
{
function __construct(){

}
}
<?php
class Model_Child_PSon extends Model_PParent
{
function __construct(){

}
}
<?php
class Model_PParent
{
function __construct(){

}
}
<?php
global $fileDir;
$fileDir = dirname(__FILE__);

$oldIncludePath = get_include_path();//获取旧的环境路径
$newIncludePath = implode(
PATH_SEPARATOR
,
array(
realpath($fileDir),
realpath($fileDir . '/library/'),
$oldIncludePath,
)
);
//新的环境路径
set_include_path($newIncludePath);//设置新的环境路径

require_once $fileDir.'/library/zend/loader/Autoloader.php';//引入zend_loader_autoloader

$loader = Zend_Loader_Autoloader::getInstance();//获取单例
$loader->registerNamespace('Model_');//注册命名空间
/*
*
* 上面的$newIncludePath包含了 项目根目录$fileDir 与 项目下的library目录
* 是由于我用的
* zend_loader_autoloader的命名空间Zend_(默认的命名空间有Zend_和Zendx_)是从library开始,
* 我自定义的命名空间Model_是从 项目根目录$fileDir开始。
*
* 注意:命名空间的区分大小写,需要与类定义的大小写对应,如Model_PParent,命名空间就必须定义为Model_
*/


$par = new Model_PParent();//使用类,前面没有显示的调用Model_PParent哦
$child = new Model_Child_PSon();
$daughter = new Model_Child_PDaughter();

总结:

使用spl_autoload_register与zend_loader_autoloader不矛盾,因为zend_loader_autoloader也是对spl_autoload_register进行封装,总之,它们还是按照注册的顺序进行加载的。

posted on 2011-03-24 10:39  samson  阅读(713)  评论(0编辑  收藏  举报

导航