• __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 ?>
    复制代码
     
     
  • 相关阅读:
    使用Azure Rest API获得Access Token介绍
    Azure Service Fabric应用程序日志记录与展现
    Azure Web App创建Python应用
    AzureWeb App如何做私有仓储的部署
    Python web在IIS上发布方法和原理
    [转载]DriverStore文件夹特别大,能删除吗?
    Azure Web APP中Local Git 如何部署分支
    Azure Web 应用如何修改 IIS 配置
    文件上传绕过
    windows下通过配置服务器安全策略指定IP地址远程访问服务器的设置方法
  • 原文地址:https://www.cnblogs.com/clphp/p/4988751.html
Copyright © 2020-2023  润新知