37

在 PHP 中是否可以执行以下操作:

myFunction( MyClass::staticMethod );

这样“myFunction”将引用静态方法并能够调用它。当我尝试它时,我收到“未定义的类常量”(PHP 5.3)的错误,所以我想这不是直接可能的,但有没有办法做类似的事情?到目前为止,我管理的最接近的方法是将“函数”作为字符串传递并使用 call_user_func()。

4

8 回答 8

36

执行此操作的“php 方式”是使用与is_callablecall_user_func完全相同的语法。

这意味着您的方法对存在是“中立的”

  • 标准函数名
  • 静态类方法
  • 实例方法
  • 关闭

对于静态方法,这意味着您应该将其传递为:

myFunction( [ 'MyClass', 'staticMethod'] );

或者如果您还没有运行 PHP 5.4:

myFunction( array( 'MyClass', 'staticMethod') );
于 2012-07-25T18:07:24.007 回答
11

由于您已经提到它call_user_func()已被使用,并且您对具有该或将静态函数作为字符串传递的解决方案不感兴趣,因此这里有一个替代方案:使用匿名函数作为静态函数的包装器。

function myFunction( $method ) {
    $method();
}

myFunction( function() { return MyClass::staticMethod(); } );

我不建议这样做,因为我认为该call_user_func()方法更简洁。

于 2012-07-25T18:06:56.167 回答
9

如果要避免使用字符串,可以使用以下语法:

myFunction( function(){ return MyClass::staticMethod(); } );

它有点冗长,但它的优点是可以进行静态分析。换句话说,IDE 可以轻松指出静态函数名称中的错误。

于 2012-07-25T20:16:44.453 回答
5

让我试着举一个详尽的例子......

你会这样打电话:

myFunction('Namespace\\MyClass', 'staticMethod');

或像这样(如果您有要传递的参数):

myFunction('Namespace\\MyClass', 'staticMethod', array($arg1, $arg2, $arg3));

以及您接收此呼叫的功能:

public static function myFunction($class, $method, $args = array())
{
    if (is_callable($class, $method)) {
        return call_user_func_array(array($class, $method), $args);
    }
    else {
        throw new Exception('Undefined method - ' . $class . '::' . $method);
    }
}

类似的技术常用于 php中的装饰器模式。

于 2014-09-19T21:18:46.470 回答
3

问题:

在 PHP 中是否可以执行以下操作:

myFunction(MyClass::staticMethod);

答案是肯定的。您可以让 staticMethod() 返回匿名函数。IE

private static function staticMethod()
{
    return function($anyParameters)
    {
        //do something here what staticMethod() was supposed to do
        // ...
        // ...
        //return something what staticMethod() was supposed to return;
    };
}

然后你可以写

myFunction(MyClass::staticMethod());

但请注意,调用 staticMethod() 需要 ()。这是因为它现在返回匿名函数,该函数包装了您最初希望您的 staticMethod() 执行的工作。

当 staticMethod() 仅作为参数传入另一个函数时,这非常有效。如果您希望调用直接进行处理的 staticMethod(),则必须编写

MyClass::staticMethod()($doPassInParameters);

请注意,与不将其包装在匿名函数中的情况相比,这可能需要一个额外的冗余步骤来检索函数指针。我只用它作为参数传递,所以不确定额外步骤的性能损失。或许可以忽略不计...

于 2017-05-02T09:43:11.650 回答
2

这是因为传递常量和函数之间的区别。传递不带括号的参数名称表示常量(MyClass::staticMethod),带括号表示静态函数(MyClass::staticMethod())。

于 2022-01-01T10:48:28.970 回答
1

这将在输出中显示第一次调用的 6 和第二次调用的 9。

$staticmethod1 = function ($max)
{
    return $max*2;
};

$staticmethod2 = function ($max)
{
    return $max*$max;
};

function myfunction($x){
    echo $x(3);
}

myfunction($staticmethod1);
myfunction($staticmethod2);
于 2012-07-25T19:43:58.143 回答
0

从 PHP 7.4 开始,这是方便且 IDE 友好的:

myFunction(fn() => MyClass::staticMethod());
于 2020-01-02T11:57:34.613 回答