__autoload 与spl_autoload_register()

PHP __autoload函数(自动载入类文件)的使用方法

作者: 字体:[增加 减小] 类型:转载 时间:2012-02-04
 
在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利
 
 
这也是OO设计的基本思想之一。在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可。下面是一个实际的例子: 
复制代码代码如下:

class ClassA{ 
public function __construct(){ 
echo “ClassA load success!”; 


//定义一个类ClassA,文件名为ClassA.php 
class ClassA{ 
public function __construct(){ 
echo “ClassA load success!”; 


class ClassB extends ClassA { 
public function __construct(){ 
//parent::__construct(); 
echo “ClassB load success!”; 


//定义一个类ClassB,文件名为ClassB.php,ClassB继承ClassA 
class ClassB extends ClassA { 
public function __construct(){ 
//parent::__construct(); 
echo “ClassB load success!”; 


定义两个测试用的类之后,我们来编写一个含有__autoload()方法的PHP运行程序文件如下: 
function __autoload($classname){ 
$classpath=”./”.$classname.'.php'; 
if(file_exists($classpath)){ 
require_once($classpath); 

else{ 
echo ‘class file'.$classpath.'not found!'; 



$newobj = new ClassA(); 
$newobj = new ClassB(); 

这个文件的运行是一点问题都没有的,可见autoload是多么的好用啊,呵呵…… 
但是不得不提醒你一下几个方面是必须要注意的。 
1、如果类存在继承关系(例如:ClassB extends ClassA),并且ClassA不在ClassB所在目录 
利用__autoload魔术函数实例化ClassB的时候就会受到一个致命错误: 
Fatal error: Class ‘Classd' not found in ……ClassB.php on line 2, 
解决方法:把所有存在extends关系的类放在同一个文件目录下,或者在实例化一个继承类的时候在文件中手工包含被继承的类; 
2、另外一个需要注意的是,类名和类的文件名必须一致,才能更方便的使用魔术函数__autoload; 
其他需要注意的事情: 
3、在CLI模式下运行PHP脚本的话这个方法无效; 
4、如果你的类名称和用户的输入有关——或者依赖于用户的输入,一定要注意检查输入的文件名,例如:.././这样的文件名是非常危险的。

 

PHP函数spl_autoload_register()用法和__autoload()介绍

作者: 字体:[增加 减小] 类型:转载 时间:2012-02-04
 
又是框架冲突导致__autoload()失效,用spl_autoload_register()重构一下,问题解决
 
 
__autoload()的用法就不再说了,以前已经在我的WEB开发笔记中说过。PHP __autoload函数(自动载入类文件)的使用方法, 原文地址:http://www.jb51.net/article/29625.htm 。 

说一说,spl_autoload_register()的用法吧,很简单,可以这样理解,就是声明一个自定义__autoload(),你可以是A函数,也可以是B函数,想怎么样就怎么样,函数体的写法,当然要和__autoload()一样就OK 了。

当PHP找不到类文件会调用这个方法,当注册了自己的函数或方法时,PHP不会调用__autoload()函数,而会调用自定义的函数 

spl_autoload_register(‘func_name'); 
spl_autoload_register(array(‘class_name','method_name')); 
详细说明如下: 
spl_autoload_register 
(PHP 5>= 5.1.2) 
spl_autoload_register — 注册__autoload()函数 
说明 
bool spl_autoload_register ([ callback $autoload_function ] ) 
将函数注册到SPL __autoload函数栈中。如果该栈中的函数尚未激活,则激活它们。 
如果在你的程序中已经实现了__autoload函数,它必须显式注册到__autoload栈中。因为 
spl_autoload_register()函数会将Zend Engine中的__autoload函数取代为spl_autoload()或 
spl_autoload_call()。 
参数 
autoload_function 
欲注册的自动装载函数。如果没有提供任何参数,则自动注册autoload的默认实现函数 
spl_autoload()。 
返回值 
如果成功则返回 TRUE,失败则返回 FALSE。 
注:SPL是Standard PHP Library(标准PHP库)的缩写。它是PHP5引入的一个扩展库,其主要功能包括autoload机制的实现及包括各种Iterator接口或类。SPL autoload机制的实现是通过将函数指针autoload_func指向自己实现的具有自动装载功能的函数来实现的。SPL有两个不同的函数spl_autoload, spl_autoload_call,通过将autoload_func指向这两个不同的函数地址来实现不同的自动加载机制。 
代码如下: 
test.class.php 
复制代码代码如下:

<?php 
class abc{ 
function __construct() 

echo 'www.chhua.com; 


?> 

load.php 
复制代码代码如下:

<?php 
class LOAD 

static function loadClass($class_name) 

$filename = $class_name.".class.php"; 
if (is_file($filename)) return include_once $filename; 


/** 
* 设置对象的自动载入 
* spl_autoload_register — Register given function as __autoload() implementation 
*/ 
spl_autoload_register(array('LOAD', 'loadClass')); 
$a = new Test();//实现自动加载,很多框架就用这种方法自动加载类 
?> 

 

在了解这个函数之前先来看另一个函数:__autoload。  

一、__autoload  

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

printit.class.php 
 
<?php 
 
class PRINTIT { 
 
 function doPrint() {
  echo 'hello world';
 }
}
?> 
 
index.php 
 
<?
function __autoload( $class ) {
 $file $class '.class.php';  
 if is_file($file) ) {  
  require_once($file);  
 }
 
$obj new PRINTIT();
$obj->doPrint();
?>

  

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

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

二、spl_autoload_register()  

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

  
 
<?
function loadprint( $class ) {
 $file $class '.class.php';  
 if (is_file($file)) {  
  require_once($file);  
 
 
spl_autoload_register( 'loadprint' ); 
 
$obj new PRINTIT();
$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 new PRINTIT();
$obj->doPrint();
?>

 

 

 

 网上关于SPL spl_autoload_register的用法的例子有很多很多,自己也查看了很多,但感觉介绍得并不太详细,使自己真正能明白其中的原理苦闷了好一会儿。现将自己的理解记录下来。

 

       关于 Standard PHP Library (SPL) 的 autoload 的方法,这些都是 PHP 5.1.2 之后才加上的方法。为了方便,这里做了一些设定。假设你有类文件,放在/home/user/class/foo.class.php, 你当前的文件为/home/user/webroot/test.php, 示例代码如下。

在文件test.php中:

复制代码
 1 <?php
 2  
 3 class autoload 
 4 { 
 5   public static function load( $class name ) 
 6   {
 7     $filename = "/home/user/class/".$classname."class.php";
 8     if (file_exists($filename )) { 
 9       require_once $filename ; 
10     } 
11   } 
12 } 
13  
14 function __autoload( $class name )
15 { // 这个是默认的 autoload 方法
16     $filename = "/home/user/class/".$classname."class.php";
17     if (file_exists($filename )) { 
18       require_once $filename ; 
19   } 
20 } 
21  
22 // 注册一个 autoloader 
23 spl_autoload_register( 'autoload::load' ); 
24 /** 
25 * __autoload 方法在 spl_autoload_register 后会失效,因为 autoload_func 函数指针已指向 spl_autoload 方法 
26 * 可以通过下面的方法来把 _autoload 方法加入 autoload_functions list 
27 */ 
28 spl_autoload_register( '__autoload' ); 
29  // 注:下面的类看上去没有定义,但其实系统根据sql_autoload_register提供的路径会自动去/home/user// /class/*.class.php下搜索foo.class.php文件,如果没找到才报错。 
30 $foo = new foo(); 
31 $foo ->bar(); 
32 ?>
复制代码
 
 
posted @ 2015-11-23 16:12  的士特啰嗦司机  阅读(294)  评论(0编辑  收藏  举报