Bug #69280 [Csd->ReO]: SoapClient classmap doesn't support fully qualified class name
| From: | nielsdos@php.net | Date: | Wed, 07 Aug 2024 08:07:38 +0000 |
| Subject: | Bug #69280 [Csd->ReO]: SoapClient classmap doesn't support fully qualified class name | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-247454@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=69280&edit=1
ID: 69280
Updated by: nielsdos@php.net
Reported by: champetier dot etienne at gmail dot com
Summary: SoapClient classmap doesn't support fully qualified
class name
-Status: Closed
+Status: Re-Opened
Type: Bug
Package: SOAP related
PHP Version: 5.6.7
Block user comment: N
Private report: N
New Comment:
Re-opened because people relied on this bug and their code stopped working, so I had to revert the
fix.
Previous Comments:
------------------------------------------------------------------------
[2024-06-01 11:32:49] git@php.net
Automatic comment on behalf of nielsdos (author) and web-flow (committer)
Revision: https://github.com/php/php-src/commit/476706165a227ea6b1d73299b9b6486a6ca073a9
Log: Fix bug #69280: SoapClient classmap doesn't support fully qualified class name
(#14398)
------------------------------------------------------------------------
[2016-02-16 16:24:41] vtsao at google dot com
I was going to file a bug for this as well, but found this one. Adding my notes as another data
point.
BACKGROUND:
I'm using SoapClient with a classmap specified in the options:
http://php.net/manual/en/soapclient.soapclient.php#refsect1-soapclient.soapclient-parameters
to map WSDL types to PHP classes. For example, I have a PHP class called NumberValue based on the
NumberValue complexType defined in:
https://ads.google.com/apis/ads/publisher/v201511/LineItemService?wsdl
NumberValue has an abstract parent class called Value.
Thus, when passed in a SoapClient::__soapCall argument:
http://php.net/manual/en/soapclient.soapcall.php#refsect1-soapclient.soapcall-parameters
and converted into SOAP XML by PHP's SoapClient, it needs an xsi:type added to its node since
it's a subclass. E.g.,
<ns1:getCreativesByStatement>
<ns1:filterStatement>
<ns1:query>WHERE id = :id ORDER BY id ASC LIMIT 1</ns1:query>
<ns1:values>
<ns1:key>id</ns1:key>
<ns1:value xsi:type="ns1:NumberValue">
<ns1:value>123456789</ns1:value>
</ns1:value>
</ns1:values>
</ns1:filterStatement>
</ns1:getCreativesByStatement>
ISSUE:
The issue is that we're using a namespace for NumberValue and if we add a prefixing
'\' in the SoapClient classmap to indicate global namespace like so:
array('NumberValue' => '\\Google\\AdsApi\\Dfp\\v201511\\NumberValue');
SoapClient doesn't seem to add the xsi:type on SOAP POSTs (outgoing SOAP calls), as it
doesn't seem to be able to map the class to the WSDL type. On SOAP responses, it seems to map
the WSDL type to class correctly as expected. E.g., it produces:
<ns1:getCreativesByStatement>
<ns1:filterStatement>
<ns1:query>WHERE id = :id ORDER BY id ASC LIMIT 1</ns1:query>
<ns1:values>
<ns1:key>id</ns1:key>
<ns1:value/>
</ns1:values>
</ns1:filterStatement>
</ns1:getCreativesByStatement>
If I remove the prefixing '\', it works. E.g.,
array('NumberValue' => 'Google\\AdsApi\\Dfp\\v201511\\NumberValue');
The prefix of '\' should not matter or affect the behaviour of SoapClient in this case
right? Is this a bug?
A related bug is that it only supports global namespaces right now anyways:
https://bugs.php.net/bug.php?id=54074
But if the SoapClient classmap were ever to respect the declared namespace then it would need to
work with a prefixing '\'.
------------------------------------------------------------------------
[2015-03-23 14:24:39] champetier dot etienne at gmail dot com
Description:
------------
If you have in your wsdl an object that extends another one
(xs:extension)(RealClass1 extends AbstractClass in my case),
then your call will succeed (soap call containing xsi:type=RealClass1) if you have in your classmap:
'RealClass1' => 'RealClass1'
but will fail (RealClass1 casted to AbstractClass) if you have:
'RealClass1' => '\RealClass1'
Same thing with namespaces:
'RealClass1' => 'myNS\RealClass1' works
'RealClass1' => '\myNS\RealClass1' doesn't work
Test script:
---------------
https://github.com/echampet/php-soapclient-classmap-bug/tree/6107d546bef50e31e1866800398a861eebeaf7d9
Expected result:
----------------
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://tempuri.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:TestMethod>
<ns1:testObj xsi:type="ns1:RealClass1">
<ns1:prop>prop</ns1:prop>
<ns1:prop1>prop1</ns1:prop1>
</ns1:testObj>
</ns1:TestMethod>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
(with xsi:type="ns1:RealClass1", and prop1)
Actual result:
--------------
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:TestMethod>
<ns1:testObj>
<ns1:prop>prop</ns1:prop>
</ns1:testObj>
</ns1:TestMethod>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
(testObj is downcasted from RealClass1 to AbstractClass and looses prop1)
(prop is a property of AbstractClass, prop1 property of RealClass1)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=69280&edit=1