Подтвердить что ты не робот

Передача статических методов в качестве аргументов в PHP

В PHP можно сделать что-то вроде этого:

myFunction( MyClass::staticMethod );

так что "myFunction" будет ссылаться на статический метод и иметь возможность его вызвать. Когда я пытаюсь, я получаю сообщение об ошибке "Undefined class constant" (PHP 5.3), поэтому, я думаю, это невозможно, но есть ли способ сделать что-то подобное? Ближайшим мне удалось до сих пор передать "функцию" в виде строки и использовать call_user_func().

4b9b3361

Ответ 1

Для этого нужно использовать тот же синтаксис, который используется is_callable и call_user_func.

Это означает, что ваш метод является "нейтральным" для

  • Стандартное имя функции
  • Статический метод класса
  • Метод экземпляра
  • Закрытие

В случае статических методов это означает, что вы должны передать его как:

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

или если вы еще не используете PHP 5.4:

myFunction( array( 'MyClass', 'staticMethod') );

Ответ 2

Поскольку вы уже упоминали, что call_user_func() был использован, и вы не заинтересованы в решении с тем или теми, которые передают статическую функцию в виде строки, вот альтернатива: использование анонимных функций в качестве обертки к статической функции.

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

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

Я бы не рекомендовал делать это, так как я думаю, что метод call_user_func() более краткий.

Ответ 3

Если вы хотите избежать строк, вы можете использовать этот синтаксис:

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

Это немного подробный, но он имеет то преимущество, что его можно подвергнуть статическому анализу. Другими словами, IDE может легко указать ошибку в имени статической функции.

Ответ 4

Позвольте мне попытаться привести подробный пример...

Вы бы сделали такой вызов:

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);
    }
}

Сибирский метод обычно используется в Decorator Pattern на php.

Ответ 5

это покажет 6 для первого вызова и 9 для второго вызова на выходе.

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

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

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

myfunction($staticmethod1);
myfunction($staticmethod2);

Ответ 6

на вопрос:

В PHP можно сделать что-то вроде этого:

myFunction (MyClass:: staticMethod);

Ответ - да. вы можете вместо staticMethod() вернуть анонимную функцию. то есть.

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);

Обратите внимание, что для извлечения указателя функции может потребоваться один дополнительный избыточный шаг по сравнению с тем, когда он может работать, не обертывая его анонимной функцией. Я использую его только как параметр, поэтому не уверен в качестве дополнительного шага. Возможно, незначительное...