【问题标题】:Find out if a method exists in a static class找出静态类中是否存在方法
【发布时间】:2010-11-12 11:57:12
【问题描述】:

我想检查我正在创建的库中是否存在一个函数,该函数是静态的。我见过 function 和 method_exists,但还没有找到允许我在相对上下文中调用它们的方法。这是一个更好的例子:

class myClass{
    function test1()
    {
        if(method_exists("myClass", "test1"))
        {
            echo "Hi";
        }
    }
    function test2()
    {
        if(method_exists($this, "test2"))
        {
            echo "Hi";
        }
    }
    function test3()
    {
        if(method_exists(self, "test3"))
        {
            echo "Hi";
        }
    }
}
// Echos Hi
myClass::test1();
// Trys to use 'self' as a string instead of a constant
myClass::test3();
// Echos Hi
$obj = new myClass;
$obj->test2();

如果函数存在,我需要能够使测试 3 回显 Hi,而无需将其从静态上下文中取出。鉴于访问类的关键字应该是“self”,因为 $this 用于分配的类。

【问题讨论】:

  • 为什么 test1() 方法不够用?
  • 因为我想把它放到一个类中,该类将被多个类扩展。我可以使用魔法常数来实现这一点,但应该有更简单的方法。

标签: php static object


【解决方案1】:

static::class 自 PHP 5.5 起可用,并将返回“Late Static Binding”类名:

class myClass {
    public static function test()
    {
        echo static::class.'::test()';
    }
}

class subClass extends myClass {}

subClass::test() // should print "subClass::test()"

get_called_class() 也是如此,并在 PHP 5.3 中引入

class myClass {
    public static function test()
    {
        echo get_called_class().'::test()';
    }
}

class subClass extends myClass {}

subClass::test() // should print "subClass::test()"

get_class() 函数,从 php 5.0.0 起不需要任何参数,如果在类中调用将返回声明函数的类的名称(例如,父类):

class myClass {
    public static function test()
    {
        echo get_class().'::test()';
    }
}

class subClass extends myClass {}

subClass::test() // prints "myClass::test()"

__CLASS__ magic constant 的作用相同 [link]。

class myClass {
    public static function test()
    {
        echo __CLASS__.'::test()';
    }
}

class subClass extends myClass {}

subClass::test() // prints "myClass::test()"

【讨论】:

  • 谢谢!这正是我想要的。
  • 我正在寻找一种方法来检查父类上是否存在静态方法,这个答案让我发现get_parent_class() 在没有任何参数的情况下调用时的工作方式相同。谢谢!
  • Just a note static::classget_called_class() 相同,self::classget_class() 相同,但它们仅在 PHP 5.5 后可用
【解决方案2】:

更新:

啊,抱歉。我暂时失明了 :) 你会想要使用魔法常数 __CLASS__

例如

if (method_exists(__CLASS__, "test3")) { echo "Hi"; }

【讨论】:

  • 这个答案似乎与问题示例的 test1() 方法相同,该方法使用 method_exists() 并将类名作为字符串传递
  • 这个想法是我不需要类名,因此我可以将方法放在任何类中,并且无论该类是否已分配,它都应该工作。
  • 你的意思是我“只是”提出主要问题的 cmets?
  • 我不明白这个问题。我看到您在 OP 中更新了您的评论:“我可以使用魔术常数来实现这一点,但应该有更简单的方法。”在我更新我的答案之前我没有看到这个。给定的方法有哪些不够简单的地方?
  • 如果可扩展性是您的目标,应注意__CLASS____TRAIT____FILE__ 等显式返回使用该常量的类/特征/文件的名称,而如果您想考虑子对象,您将需要get_class($this) 用于实例化对象,或get_called_class() 用于静态类/方法以跟踪继承。然后,您可以将一个函数放在特征或基类中并在任何地方使用它,从而防止代码重复问题,并使用instanceof [特征、父类或接口] 或method_exists() 进行验证,而不会出现重复代码。
【解决方案3】:

对于所有情况……最好的用法是……

if method_exist(…) && is_callable(…)

测试示例:

class Foo {
  public function PublicMethod() {}
  private function PrivateMethod() {}
  public static function PublicStaticMethod() {}
  private static function PrivateStaticMethod() {}
}

$foo = new Foo();

$callbacks = array(
  array($foo, 'PublicMethod'),
  array($foo, 'PrivateMethod'),
  array($foo, 'PublicStaticMethod'),
  array($foo, 'PrivateStaticMethod'),
  array('Foo', 'PublicMethod'),
  array('Foo', 'PrivateMethod'),
  array('Foo', 'PublicStaticMethod'),
  array('Foo', 'PrivateStaticMethod'),
);

foreach ($callbacks as $callback) {
  var_dump($callback);
  var_dump(method_exists($callback[0], $callback[1])); // 0: object / class name, 1: method name
  var_dump(is_callable($callback));
  echo str_repeat('-', 40), "n";
}

来源here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2020-08-06
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    相关资源
    最近更新 更多