在PHP中,使用静态类变量作为类名调用静态方法。

3

我知道你可以使用变量作为类名来调用静态方法,例如:

$className = "Foo";  
$className::Bar(); //works  

但是当我尝试像这样将静态属性用作变量时:
self::$className = "Foo";
self::$className::Bar();  //doesn't

我在调用方法的那一行遇到了以下解析错误:
Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

那么我如何使用静态属性调用该方法,是否可以使用类似于我描述的语法(不使用call_user_func和创建存储self::$className的局部变量)?


你尝试过使用call_user_func吗? - Ankh
这个语法是错误的。单词self指的是当前类作用域的类名。所以基本上,你想要表达的是“从当前类self中调用一个方法(Bar()),该方法属于类($className)”。这没有太多意义,对吧? - Avalanche
@Avalanche 嗯,没错。我不明白有什么问题,在当前类 self 中有一个属性 $className,我正在尝试调用一个与 $className 值相等的类的方法。 - Danil Solodunov
@VladimirGilevich 不会,因为我需要调用静态方法。 - Danil Solodunov
1
你有两个快速选项:要么像@rlanvin的答案建议的那样使用本地变量,要么使用PHP 7。更详细(也可能是正确的)的选项是将静态方法和属性提取到单独的类中,并使用继承和多态性来实现所需的功能。你会发现,随着生成问题的代码行的消失,你的问题也会消失。 - axiac
显示剩余2条评论
1个回答

3
你可以这样做:
$tmp = self::$className;
$tmp::Bar();

编辑

根据你的评论,似乎你的问题更多涉及面向对象设计而非语法。此外,每次给出解决方案时,你都会添加新的限制,这使得提供相关答案变得困难。

无论如何,我将尝试总结你的选项。你想要的语法目前不存在,因此你必须以某种方式绕过它。是的,这很烦人,而且这意味着你不得不做出妥协。但事实就是这样。

以下是你目前的选项:

  • 使用call_user_funcforward_static_call或类似方法。
  • 使用一个临时本地变量。如果真的很烦你,可能会将其包装成一个方法(例如static function call($method) { $tmp = self::$classname; return $tmp::$method(); },然后使用self::call('bar');
  • 重构你的对象设计,使用实例而非静态方法,这样你就不需要再这样做了。
  • 使用其他一些可怕而危险的黑客方法(例如eval(self::$classname.'::bar();');),并希望它不会反咬你一口。

那很明显,但不是我想要的。 - Danil Solodunov
这不是你想要的吗? - rlanvin
是的,但你想要的是无效的语法,这是不可能的。因此,你必须使用额外的变量来解决它(或者使用call_user_func,但你也不想那样做...) - rlanvin
我知道我写的是无效语法,这也是我首先提出问题的原因,我需要类似的东西,想知道是否有一种方法可以不使用call_user_func和创建本地变量来实现。 - Danil Solodunov
@DanilSolodunov 我已经编辑了我的答案并提供了更多细节。据我所知,你正在寻找的完美答案并不存在。 - rlanvin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接