【问题标题】:Replacement for PHP's __autoload function?替换 PHP 的 __autoload 函数?
【发布时间】:2010-04-13 14:54:51
【问题描述】:

我已经阅读了有关在需要时在这样的函数中动态加载类文件的信息:

function __autoload($className)
{
   include("classes/$className.class.php");
}

$obj = new DB();

当您创建该类的新实例时,它会自动加载 DB.class.php,但我还在几篇文章中读到,使用它是不好的,因为它是一个全局函数以及您带入项目的任何库有一个__autoload() 函数会搞砸的。

那么有人知道解决方案吗?也许另一种方法可以达到与__autoload() 相同的效果?在我找到合适的解决方案之前,我会继续使用__autoload(),因为在你引入图书馆等之前它不会开始成为问题。

谢谢。

【问题讨论】:

    标签: php class libraries autoload


    【解决方案1】:

    我已使用以下代码来使用 spl_autoload_register,如果它不存在,它将降级,并且还处理使用 __autoload 的库,您需要包含这些库。

    //check to see if there is an existing __autoload function from another library
    if(!function_exists('__autoload')) {
        if(function_exists('spl_autoload_register')) {
            //we have SPL, so register the autoload function
            spl_autoload_register('my_autoload_function');      
        } else {
            //if there isn't, we don't need to worry about using the stack,
            //we can just register our own autoloader
            function __autoload($class_name) {
                my_autoload_function($class_name);
            }
        }
    
    } else {
        //ok, so there is an existing __autoload function, we need to use a stack
        //if SPL is installed, we can use spl_autoload_register,
        //if there isn't, then we can't do anything about it, and
        //will have to die
        if(function_exists('spl_autoload_register')) {
            //we have SPL, so register both the
            //original __autoload from the external app,
            //because the original will get overwritten by the stack,
            //plus our own
            spl_autoload_register('__autoload');
            spl_autoload_register('my_autoload_function');      
        } else {
            exit;
        }
    
    }
    

    因此,该代码将检查现有的 __autoload 函数,并将其添加到堆栈以及您自己的堆栈中(因为 spl_autoload_register 将禁用正常的 __autoload 行为)。

    【讨论】:

    • 一个很好的解决方案,尽管无论如何我都会对仅使用 spl_autoload 进行一些小改动,与现有的自动加载无关,只需 spl 加载 __autoload 函数(如果存在),然后 spl 加载您的函数。
    • 是的,你可以这样做,但如果我理解正确,你只是有效地交换 if 语句。
    【解决方案2】:

    您可以使用spl_autoload_register(),将任何现有的__autoload() 魔法添加到堆栈中。

    function my_autoload( $class ) {    
        include( $class . '.al.php' );
    }
    spl_autoload_register('my_autoload');
    
    if( function_exists('__autoload') ) {
        spl_autoload_register('__autoload');
    }                                                                                         
    
    $f = new Foo;
    

    【讨论】:

      【解决方案3】:

      正确的方法是使用spl_autoload_register。要保存某个第 3 方引入的 __autoload 函数,您也可以将该函数放在自动加载器堆栈中:

      if (function_exists('__autoload')) {
          spl_autoload_register('__autoload');
      }
      

      【讨论】:

        【解决方案4】:

        使用 spl_autoload_register 代替 __autoload。这将允许您将自动加载功能添加到堆栈中。

        【讨论】:

        • 我认为 spl_autoload_register 破坏了任何现有的 __autoload 函数,所以如果一个库使用它,你正在清除该库的函数。话虽如此,如果两个库都定义了一个__autoload 函数,那你就有点搞砸了!
        • 如果您的代码有一个现有的 __autoload 函数,那么这个函数必须在 __autoload 堆栈上显式注册。这是因为 spl_autoload_register() 将通过 spl_autoload() 或 spl_autoload_call() 有效地替换 __autoload 函数的引擎缓存。这取自手册页
        【解决方案5】:

        您可以使用Zend_Loader。 (假设 Zend Framework 可供您使用...)

        【讨论】:

          【解决方案6】:

          您能做的最好的事情就是定义自己的对象,负责为您正在编程的任何子系统自动加载。

          例如:

          class BasketAutoloader
          {
            static public function register()
            {
              spl_autoload_register(array(new self, 'autoload'));
            }
          
            public function autoload($class)
            {
              require dirname(__FILE__).'/'.$class.'.php';
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多