1

This is somewhat the second part to this question.

In my project, I have the following interface:

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

Now I have several classes that implement this interface and I want to call several of these methods on each of those classes.

So there are 2 ways I can invoke those methods. The pre-5.3 version:

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

And the post-5.3 version:

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

Now, my problem is, the pre-5.3 version doesn't work at all in 5.3.3.
Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given
Even though I am pretty sure it worked fine with 5.3.0. The documentation also states:

Referenced variables in param_arr are passed to the function by reference, regardless of whether the function expects the respective parameter to be passed by reference. This form of call-time pass by reference does not emit a deprecation notice, but it is nonetheless deprecated, and will most likely be removed in the next version of PHP.

So I thought I was being real smart by cooking this up:

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

Turns out, it wasn't smart at all, as $provider::something() generates a parser error (Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM).

So, what is the way of calling those static methods on those classes (when the class name is provider as a string) that works on PHP 5.2.6 (Debian 5) through 5.3.3 (Debian 6).

Community
  • 1
  • 1
Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138

2 Answers2

1

Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given

Using call_user_func instead of call_user_func_array should fix that.

Markus Hedlund
  • 23,374
  • 22
  • 80
  • 109
1

As Znarkus wrote, you're not passing a reference to Foo::registerSoapTypes,

so just add an & to those parameters that need to be passed as references, in the second parameter of your call_user_func_array

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

But if not all your methods expects the parameters to be a reference, you could run into some problems, so maybe it's safer to construct the $args for call_user_func_array using some reflection.

See: http://www.php.net/manual/en/book.reflection.php

and especially: http://www.php.net/manual/en/reflectionparameter.ispassedbyreference.php

Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • Somehow I thought that wasn't legal as well. Given that the documentation states: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. – Oliver Salzburg May 16 '11 at 17:52