如何检查SPL堆栈中是否已存在某个功能?

时间:2012-02-27 06:53:09

标签: php spl-autoload-register

我正在尝试使用spl_autoload_register,我想创建一个if()语句,用于检查类方法是否已经注册。

例如:

if (spl_autoload_function(array($this, '_loadClass'))
    // Then do nothing
else
    // Then run spl_autoload_register(array($this, '_loadClass));

是否可以使用上述代码/方法?

2 个答案:

答案 0 :(得分:3)

  

我正在尝试自动加载器,我想创建一个if语句来检查类方法是否已经注册。

你不应该。没有必要做if语句; spl_autoload_register将忽略具有相同参数的第二个调用:

<?php

$foo = function( $class ) {
    return false;
};

spl_autoload_register( $foo );
var_dump( spl_autoload_functions( ) );

spl_autoload_register( $foo );
var_dump( spl_autoload_functions( ) );

输出显示虽然我们两次调用spl_autoload_register,但仍然只有一个自动加载器;

array(1) {
  [0]=>
  object(Closure)#1 (1) {
    ["parameter"]=>
    array(1) {
      ["$class"]=>
      string(10) "<required>"
    }
  }
}
array(1) {
  [0]=>
  object(Closure)#1 (1) {
    ["parameter"]=>
    array(1) {
      ["$class"]=>
      string(10) "<required>"
    }
  }
}

如果你想确保一个类没有自己注册两次,你当然可以在某种静态成员中设置它;

<?php
class Foo {
    protected static $registered = false;

    public function register( ) {
        if( self::$registered !== false ) {
            return;
        }
        echo "spl_autoload_register( \$this, '_loadClass' );\n";
        self::$registered = true;
    }
}

$foo = new Foo( );
$foo->register( );

$bar = new Foo( );
$bar->register( );

输出显然是一行:

spl_autoload_register( $this, '_loadClass' );

那说,为什么要编写自己的自动加载器?已经有很多,很难相信它们都不符合你的要求。

答案 1 :(得分:0)

免责声明:我不完全自信我理解你的问题,但我有足够的信心,我以为我会尝试回答。


没有spl_*功能来执行此操作。你得到的最接近的是spl_autoload_functions(),它返回spl用来加载的函数,而不是正在加载的函数。

<强>解决方案:

编写自己的加载器,在加载函数/类时记录,并使用spl_autoload_register进行注册。


回答评论:如果您有一个加载函数的类,请将其附加到已加载的类的内部数组。

class Autoloader {

    protected $loaded = array();

    function autoload($class) {
        // find class location
        // if it is found:
        // include class
        $this->loaded[] = $class;
    }

    function hasLoaded($class) {
        return in_array($class, $this->loaded);
    }

}

$autoloader = new Autoloader();
spl_autoload_register(array($autloader, 'autoload'));

如果您不想知道自动加载器是否加载了它,您只需使用class_exists检查是否存在。