PHP5 AutoLoader SPL_AutoLoad 失败

发布于 2024-12-02 10:36:38 字数 3873 浏览 0 评论 0原文

我将下面的代码作为自动加载类,但是 clean 方法似乎根本不起作用,并且它总是依赖于 dirty 方法。

我是否错误地使用了 spl_autoload ?如果是这样,正确(更好)的方法是什么?这是否效率低下,如何改进?

不过,在使用此方法时,我总是得到诸如底部之类的输出,并且在某些情况下,它只是找不到该类,但不会抛出任何错误我已将显示错误设置为 1 并已检查错误日志但完全丢失了。

代码初始化为

require "vendor/AutoLoader.class.php";
self::setGlobal("autoloader", AutoLoader::init());

类如下:

public static $instance;
private $_src=array('vendor/', 'lib/', '');
private $_sub=array('base/', '');
private $_ext=array('.php', 'class.php', 'lib.php');

/* initialize the autoloader class */
public static function init(){
    if(self::$instance==NULL){
        self::$instance=new self();
    }
    return self::$instance;
}

/* put the custom functions in the autoload register when the class is initialized */
private function __construct(){
    spl_autoload_register(array($this, 'clean'));
    spl_autoload_register(array($this, 'dirty'));
}

/* the clean method to autoload the class without any includes, works in most cases */
private function clean($class){
    $class=str_replace('_', '/', $class);
    spl_autoload_extensions(implode(',', $this->_ext));
    foreach($this->_src as $resource){
      foreach($this->_sub as $sub){
        echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
        set_include_path(pegFramework::getGlobal("baseDir") . $resource.$sub);
        spl_autoload($class);
        if(class_exists($class)) {
          echo 'Found and clean included '.$class.' in '.$resource.$sub."<br />";
          break 2;
        }
      }
    }
}

/* the dirty method to autoload the class after including the php file containing the class */
private function dirty($class){
    global $docroot;
    $class=str_replace('_', '/', $class);
    foreach($this->_src as $resource){
        foreach($this->_ext as $ext){
          foreach($this->_sub as $sub){
            echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
            if(@include(pegFramework::getGlobal("baseDir") . $resource . $sub. $class . $ext)) {
              echo 'Found and dirty included '.$class.' as '.$resource . $sub. $class . $ext."<br />";
              break 3;
            }
          }
        }
    }
    spl_autoload($class);
}

Trying to load pegDatabase via pegAutoloader::clean()
...snip...
Trying to load pegDatabase via pegAutoloader::clean()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load basepegDatabase via pegAutoloader::clean()
...snip...
Trying to load basepegDatabase via pegAutoloader::clean()
Trying to load basepegDatabase via pegAutoloader::dirty()
Found and dirty included basepegDatabase as vendor/base/basepegDatabase.php
Found and dirty included pegDatabase as vendor/pegDatabase.php
Trying to load pegRequest via pegAutoloader::clean()
...snip...
Trying to load pegRequest via pegAutoloader::clean()
Trying to load pegRequest via pegAutoloader::dirty()
Trying to load pegRequest via pegAutoloader::dirty()
Found and dirty included pegRequest as vendor/pegRequest.php
Trying to load pegFacebook via pegAutoloader::clean()
...snip...
Trying to load pegFacebook via pegAutoloader::clean()
Trying to load pegFacebook via pegAutoloader::dirty()
...snip...
Trying to load pegFacebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::clean()
Trying to load Facebook via pegAutoloader::clean()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()

I have the code below as an autoload class, however it appears that the clean method simply isn't working and it always falls back on the dirty method.

Am I using spl_autoload incorrectly? If so what is the correct (better) way? Is this inefficient, how could it be improved?

I always get output such as the bottom when using this method though, and in some cases it just doesn't find the class but doesn't throw any error I have display errors set to 1 and have checked the error log but just completely missing.

The code gets initialised as

require "vendor/AutoLoader.class.php";
self::setGlobal("autoloader", AutoLoader::init());

And the class is as follows:

public static $instance;
private $_src=array('vendor/', 'lib/', '');
private $_sub=array('base/', '');
private $_ext=array('.php', 'class.php', 'lib.php');

/* initialize the autoloader class */
public static function init(){
    if(self::$instance==NULL){
        self::$instance=new self();
    }
    return self::$instance;
}

/* put the custom functions in the autoload register when the class is initialized */
private function __construct(){
    spl_autoload_register(array($this, 'clean'));
    spl_autoload_register(array($this, 'dirty'));
}

/* the clean method to autoload the class without any includes, works in most cases */
private function clean($class){
    $class=str_replace('_', '/', $class);
    spl_autoload_extensions(implode(',', $this->_ext));
    foreach($this->_src as $resource){
      foreach($this->_sub as $sub){
        echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
        set_include_path(pegFramework::getGlobal("baseDir") . $resource.$sub);
        spl_autoload($class);
        if(class_exists($class)) {
          echo 'Found and clean included '.$class.' in '.$resource.$sub."<br />";
          break 2;
        }
      }
    }
}

/* the dirty method to autoload the class after including the php file containing the class */
private function dirty($class){
    global $docroot;
    $class=str_replace('_', '/', $class);
    foreach($this->_src as $resource){
        foreach($this->_ext as $ext){
          foreach($this->_sub as $sub){
            echo 'Trying to load ', $class, ' via ', __METHOD__, "()<br />";
            if(@include(pegFramework::getGlobal("baseDir") . $resource . $sub. $class . $ext)) {
              echo 'Found and dirty included '.$class.' as '.$resource . $sub. $class . $ext."<br />";
              break 3;
            }
          }
        }
    }
    spl_autoload($class);
}

Trying to load pegDatabase via pegAutoloader::clean()
...snip...
Trying to load pegDatabase via pegAutoloader::clean()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load pegDatabase via pegAutoloader::dirty()
Trying to load basepegDatabase via pegAutoloader::clean()
...snip...
Trying to load basepegDatabase via pegAutoloader::clean()
Trying to load basepegDatabase via pegAutoloader::dirty()
Found and dirty included basepegDatabase as vendor/base/basepegDatabase.php
Found and dirty included pegDatabase as vendor/pegDatabase.php
Trying to load pegRequest via pegAutoloader::clean()
...snip...
Trying to load pegRequest via pegAutoloader::clean()
Trying to load pegRequest via pegAutoloader::dirty()
Trying to load pegRequest via pegAutoloader::dirty()
Found and dirty included pegRequest as vendor/pegRequest.php
Trying to load pegFacebook via pegAutoloader::clean()
...snip...
Trying to load pegFacebook via pegAutoloader::clean()
Trying to load pegFacebook via pegAutoloader::dirty()
...snip...
Trying to load pegFacebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::clean()
Trying to load Facebook via pegAutoloader::clean()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()
Trying to load Facebook via pegAutoloader::dirty()
...snip...
Trying to load Facebook via pegAutoloader::dirty()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蘑菇王子 2024-12-09 10:36:38

我认为是对 spl_autoload 的调用让你绊倒了。在php文档的注释中,我发现这个

请注意,此函数会将其查找的类名小写,当找不到 Foo_Bar.php 时不要感到困惑

因此,使用 pegFacebookFacebook 调用 spl_autoload code> 将触发对名为 pegfacebook.phpfacebook.class.php 的文件的搜索。

不过,如果我是你,我会看看 Symfony 的 UniversalClassLoader 作为示例更简化的类加载处理。您可能可以调整它以使用特定的扩展,但我至少会考虑找到一种新的方法来处理这个问题。

I think it's the call to spl_autoload that's tripping you up. In the comments of the php documentation, I found this:

Note this function will LOWERCASE the class names its looking for, dont be confused when it cant find Foo_Bar.php

So, calls to spl_autoload with pegFacebook or Facebook are just going to trigger searches for files named pegfacebook.php or facebook.class.php.

If I were you, though, I would look at Symfony's UniversalClassLoader for examples of much more simplified handling of class loading. You could probably tweak it to use specific extensions, but I would at least think about finding a new way to handle this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文