Вызов статического метода класса по имени - PullRequest
1 голос
/ 16 мая 2011

Это в некоторой степени вторая часть к этому вопросу .

В моем проекте у меня есть следующий интерфейс:

interface ISoapInterface {
  public static function registerSoapTypes( wsdl &$wsdl );
  public static function registerSoapOperations( NuSoapServer &$server );
  public static function registerFaultHandler( $callback );
  public static function handleFault( $faultcode, $faultstring, $faultdetail );
  public static function userInfo( User $user );
}

Теперь у меня есть несколько классов, которыереализовать этот интерфейс, и я хочу вызвать несколько из этих методов для каждого из этих классов.

Таким образом, я могу вызвать эти методы двумя способами.Версия до 5.3:

call_user_func_array( array( $provider, "registerSoapTypes" ), array( $server->wsdl ) );

И версия после 5.3:

$provider::registerSoapTypes( $server->wsdl );

Теперь моя проблема в том, что версия 5.3 вообще не работает в 5.3.3.
Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given
Хотя я почти уверен, что с 5.3.0 он работает нормально. В документации также говорится:

Переменные, указанные в param_arr, передаются в функцию по ссылке, независимо от того, ожидает ли функция передачи соответствующего параметра по ссылке.Эта форма передачи времени вызова по ссылке не выдает уведомления об устаревании, но, тем не менее, устарела и, скорее всего, будет удалена в следующей версии PHP.

Поэтому я подумал, что я действительно умный, придумав это:

$soapProvider = array( "Foo", "Bar", "Foo2", "Bar2" );
foreach( $soapProvider as $provider ) {

  if( !defined( "PHP_VERSION_ID" ) ) {
    $version = explode( ".", PHP_VERSION );
    define( "PHP_VERSION_ID", ( $version[ 0 ] * 10000 + $version[ 1 ] * 100 + $version[ 2 ] ) );
  }

  if( PHP_VERSION_ID > 50300 ) {
    // Use simple calling method on systems running PHP 5.3.0 or higher
    $provider::registerSoapTypes( $server->wsdl );
    $provider::registerSoapOperations( $server );
    $provider::registerFaultHandler( "faultHandler" );
    $provider::userInfo( $user );

  } else {
    call_user_func_array( array( $provider, "registerSoapTypes" ), array( $server->wsdl ) );
    call_user_func_array( array( $provider, "registerSoapOperations" ), array( $server ) );
    call_user_func_array( array( $provider, "registerFaultHandler" ), array( "faulthandler" ) );
    call_user_func_array( array( $provider, "userInfo" ), array( $user ) );
  }
}

Оказывается, это было совсем не умно, так как $provider::something() генерирует ошибку парсера (Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM).

Итак, как можно вызывать эти статические методы в тех классах (когда имя класса является провайдером в виде строки), который работает на PHP 5.2.6 (Debian 5) - 5.3.3 (Debian 6).

Ответы [ 2 ]

1 голос
/ 16 мая 2011

Как писал Знаркус, вы не передаете ссылку на Foo::registerSoapTypes,

, поэтому просто добавьте & к тем параметрам, которые необходимо передать в качестве ссылок, во второмпараметр вашего call_user_func_array

call_user_func_array( array( $provider, "registerSoapTypes" ), array( &$server->wsdl ) );

Но если не все ваши методы ожидают, что параметры будут ссылочными, вы можете столкнуться с некоторыми проблемами, поэтому, возможно, безопаснее построить $ args для call_user_func_arrayнемного размышлений.

См .: http://www.php.net/manual/en/book.reflection.php

и особенно: http://www.php.net/manual/en/reflectionparameter.ispassedbyreference.php

1 голос
/ 16 мая 2011

Параметр 1 для Foo :: registerSoapTypes () должен быть ссылкой, значение

Использование call_user_func вместо call_user_func_array должно исправить это.

...