4

how can I set a parameter by ref in nusoap. in following code I should set two parameters by ref (status and recId). note that & not working:

        $params = array(
        'username' => GATEWAY_USERNAME,
        'password' => GATEWAY_PASSWORD,
        'from' => GATEWAY_NUMBER,
        'to' => array($to),
        'text' => $message,
        'flash' => $flash,
        'udh' => '',
        'status' => &$status,
        'recId' => &$recId
    );

    $sendParams=array($params);
    $res=$this->client->call('Send',$sendParams);
m3hdi
  • 383
  • 1
  • 4
  • 15
  • are `status` and `recId` primitive types? – manix Mar 31 '15 at 19:15
  • try `$res=$this->client->call('Send', &$sendParams);` – manix Mar 31 '15 at 19:16
  • Ok, I put a bounty on this very old questions because I couldn't find an answer anywhere.What I'm trying to do is almost the same as the OP. I'm trying to pass a string by reference and put a value into it inside the funcion. And no, putting the & didn't work. – undefined Mar 31 '15 at 19:28
  • putting a `&` in primitive values do not work. You should use a class instead – manix Mar 31 '15 at 19:40
  • What do you want to achieve with this? do you aspect that the function call is changing those values? Can you explain me a little bit more. – borracciaBlu Apr 02 '15 at 01:16
  • I need the function to: 1 - return a boolean. 2 - change the value from the $xml parameter, returning a XML based on the boolean that is being returned. – undefined Apr 02 '15 at 12:04

2 Answers2

2

About passing the values by reference:

function test_reference_in(&$array) {
    $array['a'] = 2;
}

$test_array['a'] = 1;
test_reference_in($test_array);
echo $test_array; //-> it prints 2

About nusoap:

Now in nusoap the client class is nusoap_client.
In that class you have nusoap_client::call() to make the soap call.

This is what appen in nusoap_client::call() to the array $params which is your $sendParams in your example.
I'm going to omit all the rest of the method that is not related to $params to explain better what's going on.

/**
 * Pseudocode of call to explain the operations on $params
 * @see nusoap_client::call()
 */
function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
    /*
       some code 
       .
       .
       .

     */
    // varDump is just var_dump so print $params 
    $this->appendDebug('params=' . $this->varDump($params));
     /*
       some code 
       .
       .
       .

     */ 

    /*
     * Here $params has been read, no write operation in there 
     * about serializeRPCParameters @see class.wsdl.php again is just reading
     */
    if (is_string($params)) {
        $this->debug("serializing param string for WSDL operation $operation");
        $payload = $params;
    } elseif (is_array($params)) {
        $this->debug("serializing param array for WSDL operation $operation");
        $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
    } else {
        $this->debug('params must be array or string');
        $this->setError('params must be array or string');
        return false;
    }

    /*
     * Here again $params has been read, no write operation in there 
     */
    if (is_string($params)) {
        $this->debug("serializing param string for operation $operation");
        $payload = $params;
    } elseif (is_array($params)) {
        $this->debug("serializing param array for operation $operation");
        foreach($params as $k => $v){
            $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
        }
    } else {
        $this->debug('params must be array or string');
        $this->setError('params must be array or string');
        return false;
    }
}   

So as you can see here there are no advantages to pass $params by reference.

Because:

  1. $params is not modified in any way in nusoap_client::call()
  2. Even if you modify $params somewhere else after you have to use again nusoap_client::call()

What if you want to pass $params by reference in any case? Can I do it?

Well yes you can!
To achieve that you have to copy nusoap_client.php and call it nusoap_client_new.php.
In there modify the class name form nusoap_client to nusoap_client_new.

// From this 
class nusoap_client extends nusoap_base  {

// To this 
class nusoap_client_new extends nusoap_base  {

Modify the nusoap_client_new::call() method adding the ref in params like this :

/*
 * Please note &$params=array() instead of $params=array()
 */
function call($operation,&$params = array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
    /**
     * Of course here you have to modify your code to make some operation on $params
     * according to your needs.
     */
     /*
       original code 
       .
       .
       .

     */ 
}

At the end update your code to require and use nusoap_client_new::call() instead of nusoap_client::call().

borracciaBlu
  • 4,017
  • 3
  • 33
  • 41
1

Excusively for Gustavo.

Up from version of PHP 5.4:

Call-time pass by reference has been removed.

What does it mean is, in version <= PHP 5.3 code like that should work:

function appendA($string) {
    $stringA .= 'A';
}

$string = '';
appendA(&$string);

but is no longer working later. For PHP 5.4+ to make a function that is editing its parameters by reference, you have to declare it this way from the very beggining. Eg:

function appendA(&$string) { // <- first change
    $stringA .= 'A';
}

$string = '';
appendA($string); // <- second change

Please note, that with PHP 5.4+, trying to call function with appendA(&$string) will produce an notice and not change value by reference.

According to original question, I have not found place, where $params are changed during client::call() function in nusoap, so I see no point in providing them by reference but I may be blind. Anyway method is not declared in way compatible with PHP 5.4+, so & near parameter during method call will not work with those PHP versions. Method modification is required in that case.

yergo
  • 4,761
  • 2
  • 19
  • 41