Bug #71763 [Com]: Soap failed if param WAS reference

From: Date: Thu, 30 Jun 2016 13:55:36 +0000
Subject: Bug #71763 [Com]: Soap failed if param WAS reference
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201942@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71763&edit=1

 ID:                 71763
 Comment by:         tero dot tasanen at gmail dot com
 Reported by:        ppbg at andreika dot info
 Summary:            Soap failed if param WAS reference
 Status:             Open
 Type:               Bug
 Package:            Arrays related
 PHP Version:        7.0.4
 Block user comment: N
 Private report:     N

 New Comment:

Correction to previous code example. It should of course be:
  $item->rows = getRows($item->id);


Previous Comments:
------------------------------------------------------------------------
[2016-06-30 13:46:48] tero dot tasanen at gmail dot com

We are also having a same problem, but with in SoapServer context. If a variable (array of objects)
has a reference the soap action will return an array of empty elements. See the example below. When
the reference is removed,  I don't know either if this is soap related, but I was not able to
reproduce this with a separate test script. 

I think this is a really critical bug. This was working as it should in all versions before php7.




-------

public function getSalesOrders() {
  $data = [new SalesOrder()];

  foreach($data as &$item) { // ref here breaks the response.
    $data->rows = getRows($item->id);
  }

  return $data;
}
--------
<SOAP-ENV:Envelope>
   <SOAP-ENV:Body>
      <ns1:getSalesOrdersResponse>
         <getSalesOrdersReturn SOAP-ENC:arrayType="ns1:SalesOrder[3]"
xsi:type="ns1:SalesOrderArray">
            <item xsi:type="ns1:SalesOrder"/>
            <item xsi:type="ns1:SalesOrder"/>
            <item xsi:type="ns1:SalesOrder"/>
         </getSalesOrdersReturn>
      </ns1:getSalesOrdersResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


-------

And yes, I know that the reference is not needed in my case, but there might be cases where it was
needed. This was just something we noticed when upgrading to php7.

------------------------------------------------------------------------
[2016-06-14 08:28:50] msmit at quovide dot com

I have a similar issue. I present you a complete test case:

<?php

/** Function that is the culprit **/
function filter($o)
{
	if(is_array($o))
	{
		foreach($o as &$v)
		{
			$v = filter($v);
		}
		
		return $o;
	}
	
	return $o;
}

/**
 * Test class
 */
class TestClient extends SoapClient
{

	public function __construct()
	{
		parent::__construct('http://www.ripedev.com/webservices/localtime.asmx?WSDL');
	}

	public function __doRequest($request, $location, $action, $version, $one_way = NULL)
	{
		echo htmlentities($request);
		die();
	}
}

$args = array(
	"ZipCode" => null 
);

/**
 * When commentend (ZipCode not there):
 * <?xml version="1.0" encoding="UTF-8"?>
 * <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.ripedev.com/">
 * <SOAP-ENV:Body>
 * <ns1:LocalTimeByZipCode/>
 * </SOAP-ENV:Body>
 * </SOAP-ENV:Envelope>
 *
 * When uncommented (zipCode is now an empty string??):
 * <?xml version="1.0" encoding="UTF-8"?>
 * <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.ripedev.com/">
 * <SOAP-ENV:Body>
 * <ns1:LocalTimeByZipCode>
 * <ns1:ZipCode></ns1:ZipCode>
 * </ns1:LocalTimeByZipCode>
 * </SOAP-ENV:Body>
 * </SOAP-ENV:Envelope>
 */
// $args = filter($args);

// Both show same var_dump:

// var_dump($args);
// array(1) { ["ZipCode"]=> NULL }
// var_dump(filter($args));
// array(1) { ["ZipCode"]=> NULL }

$client = new TestClient();
$client->LocalTimeByZipCode($args);

------------------------------------------------------------------------
[2016-03-10 03:00:25] ppbg at andreika dot info

/

------------------------------------------------------------------------
[2016-03-10 02:56:28] ppbg at andreika dot info

Description:
------------
I got strange behavour in soap extension but I think it is not soap-related.

If I call soap method with "complex" params I lost some tags in request ( it can be
invalid and dropped while wsdl schema validation ? ) if that param was reference

reproduced in ubuntu and centos (remi package) with 7.0.3 and 7.0.4

Test script:
---------------
$client = new \SoapClient('WebStoreWS.xml', [
            'trace' => true,
        ]);
$params = [
  'p' => [
    'param1' => 'OK',
    'param2' => [
      'item' => 1,
      'item2' => 2
    ]
  ]
];

if ( MAKEREF || UNLINKIT || FIXME) {
  // make ref
  $p = &$array['p']['param2'];
  if ( UNLINKIT) {
     //remove ref
     unset($p);
  }
  if (FIXME) {
// "touch" any key of array to fix problem
   $array['p']['param2']['item'] =
$array['p']['param2']['item'];
 }
} 



try {
  $client->myFunc($params);
} catch(\Exception $e) {
  echo $client->__getLastRequest();
}

Expected result:
----------------
// it works in php5.6 (all params) and php7.0.4 with !MAKEREF OR FIXME= true
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope ...>
  <p>
    <param1>OK</param1>
    <param2>
      <item>1</item>
      <item2>2</item2>
    </param2>
  </p>
</SOAP-ENV>

Actual result:
--------------
// it fails in php7.0.4 with MAKEREF AND !FIXME
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope ...>
  <p>
    <param1>OK</param1>
  </p>
</SOAP-ENV>

so if we made a reference in subarray of params we got problems even unlink reference. But if we
change any param of subarray (even on the same value) the problem will be fixed. 


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=71763&edit=1


Thread (6 messages)

« previous php.bugs (#201942) next »