【问题标题】:PHP callback: Is there an equivalent for ::class for a method of a class?PHP 回调:类的方法是否有 ::class 的等价物?
【发布时间】:2023-03-23 04:55:02
【问题描述】:

在 PHP 中,可以通过类名解析获得完整的类名,如下所示:

例子:

namespace Name\Space;
class ClassName {}

echo ClassName::class;

输出:Name\Space\ClassName

这比直接在代码中使用字符串Name\Space\ClassName 更好,因为代码自省,尤其是在 IDE 中可以直接发现错误。

我想知道类的方法是否有类似的东西 - 这对于回调函数特别有用。

这就是你基本上可以传递回调的方式:

$a = function($callback,$arg) { return $callback($arg); }

$a('getInfo',5);

我宁愿做这样的事情,而不是在这里传递一个字符串(可能会改变):

$a(MyClass::class::getInfo,5);

在 IDE 中单击“转到声明”后,我可以直接转到 getInfo,而且如果方法不再存在,我会看到错误。有没有办法在这里实现我想做的事情?

【问题讨论】:

  • Possible duplicate。一些有用的信息可以在问题下的 cmets 中找到,而不仅仅是在答案中。
  • @El_Vanja 非常感谢您,这基本上是同一个问题,这是一个很好的讨论。对于重复,我认为stackoverflow指南说“这里已经有了答案”。但似乎没有足够的答案,所以它可能是 PHP 功能请求?还是有人想出了一个现代的解决方案?
  • 我只是手动链接作为可能的重复,因为虽然本质上是在问同样的事情,但该问题的作者非常具体地寻找速记表达式,我不确定那里的信息是否会提供为您的案件提供满意的答复。
  • @El_Vanja 是的 - 谢谢。我的问题有点宽泛,但答案很可能是相同的。

标签: php callback introspection


【解决方案1】:

实际上,您使用的是可调用类型。 PHP 只允许将方法/函数名称设置为字符串。但是如果你使用类和对象,你将有不同的方式来设置回调。例如:

$a = function($callback, $arg) { 
   return call_user_func($callback, $arg)); 
}

// call a static method of the class with 
// using fullname space and method name as a string
$a('Name\Space\MyClass::getInfo',5); 

// call a static method of the class 
// with using ::class 
$a([MyClass::class, 'getInfo'], 5);

// call a method of an object 
$myObject = new MyClass();
$a([$myOject, 'getInfo'], 5);

【讨论】:

  • 感谢您的解释。使用is_callable,您甚至可以检查 call_user_func 是否可以工作,但这仍然是运行时的动态检查,IDE 无法帮助您 - 例如拼写错误?
  • @Blackbam 是的,在这种情况下,您不能使用 IDE 的自动完成功能,但例如,在 PHPStorm 中,您可以使用 CTRL+左键组合来导航这些方法。它可以用作一种正确性检查
【解决方案2】:

三种可能。

(1)

echo `__CLASS__`;

...将namespace\classname 作为字符串返回。

(2)

如果您尝试从另一个类(即不是您当前正在执行代码的类)获取命名空间\类名,那么我建议在每个类中设置一个公共属性,例如:

public static $classname = __CLASS__;

然后您可以从任何地方访问:

ClassName::$classname

把它放在你的每个班级。始终使用相同的属性名称。

(3)

您是否考虑过 PHP 函数 debug_backtrace(),它返回一个调用堆栈,最近一次调用位于 index = 0;

所以,如果:

$caller = debug_backtrace();

然后,$caller[0]['class'] 在您调用 debug_backtrace() 的位置包含完全限定的类名,包括任何命名空间。

我猜#2 是适合您的解决方案。

刚刚想到了第 4 种可能性,它不依赖于您向每个类添加任何代码。虽然可能会增加一些开销,但我上面的第 3 个解决方案也是如此。

(4)

$declared_classes = get_declared_classes();

这列出了当前在 PHP 范围内声明为完全限定命名空间\类名的所有类。您可以在返回的数组中搜索数组中的部分字符串匹配项,并返回整个命名空间\类名字符串。

要记住的一件事。如果不同的命名空间有同名的类,你可能会有重复。

【讨论】:

  • 类的好答案,但如何获得没有硬编码字符串的类方法?
  • 我不明白你的问题@Blackbam。在某些时候,您必须知道要搜索的内容是包含方法名称的变量,还是硬编码的方法。还有另一个 PHP 调用:get_class_methods() 返回类中的所有公共方法,get_class_vars() 返回类中的所有公共属性。一旦你知道了类,get_declared_classes() 将返回 PHP 范围内的完全限定 (namespace\class) 列表。
猜你喜欢
  • 1970-01-01
  • 2013-11-06
  • 2010-11-15
  • 2019-03-11
  • 2022-09-23
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多