【问题标题】:How can I check if a function already exists in the SPL stack?如何检查 SPL 堆栈中是否已存在函数?
【发布时间】:2012-02-27 06:53:09
【问题描述】:

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

例如:

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

上面的代码/方法可以吗?

【问题讨论】:

  • 可能是这样的? if (defined('foo')) { ... }
  • 我认为定义与定义而不是类有关,嗯,但我想真正检查它是否在 SPL 堆栈中,而不是函数是否已定义。
  • 如果它的loaded = true,它可以在类内部或外部工作的闪存
  • the SPL stack 是什么意思? SplStack 类?
  • 是的,我想检查一个类方法是否已经被加载

标签: php spl-autoload-register


【解决方案1】:

我正在尝试做一个自动加载器,我想创建一个 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' );

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

【讨论】:

  • 学习经验,我们不能都用别人的代码来磨练我们的PHP技能=)
  • 很公平,学习其实是一个非常有效的问题答案:)
【解决方案2】:

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


没有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 简单地检查是否存在。

【讨论】:

  • 我做了一个自动加载器来加载我的类,但我想检查一个类是否已经加载。通过这样做,我已经使用了 spl_autoload_register
  • hmmm,如果我在内部使用spl_autoload_register,如果我指定class_exists(__CLASS__),这会影响自动加载过程吗?
  • 使用class_exists 不会触发自动加载器。
  • 如果你想在没有加载的情况下检查类是否存在,使用class_exists('FooClass', false); - 见php.net/class_exists
  • class_exists(__CLASS__) 完全没有意义。要填充 CLASS,您必须位于类方法/函数中。为此,必须加载该类。另请注意,CLASS 不会解析为 OOP 中的扩展类,但始终是它所放入的类。
猜你喜欢
  • 2011-01-07
  • 2013-12-06
  • 2021-06-30
  • 2012-12-07
  • 2012-12-31
  • 1970-01-01
  • 2020-12-19
  • 2014-02-18
  • 2015-07-24
相关资源
最近更新 更多