使用带有XML主体的PHP创建SOAP调用
我正在尝试使用PHP调用SOAP方法.
I'm trying to call a SOAP method using PHP.
这是我得到的代码:
$data = array('Acquirer' =>
array(
'Id' => 'MyId',
'UserId' => 'MyUserId',
'Password' => 'MyPassword'
));
$method = 'Echo';
$client = new SoapClient(NULL,
array('location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler',
'uri' => 'http://example.com/wsdl', 'trace' => 1));
$result = $client->$method($data);
这是它创建的请求:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:Echo>
<param0 xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">Acquirer</key>
<value xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">Id</key>
<value xsi:type="xsd:string">mcp</value>
</item>
<item>
<key xsi:type="xsd:string">UserId</key>
<value xsi:type="xsd:string">tst001</value>
</item>
<item>
<key xsi:type="xsd:string">Password</key>
<value xsi:type="xsd:string">test</value>
</item>
</value>
</item>
</param0>
</ns1:Echo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
这是我想要的要求,如下所示:
And here's what I want the request to look like:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<Echo>
<Acquirer>
<Id>MyId</Id>
<UserId>MyUserId</UserId>
<Password>MyPassword</Password>
</Acquirer>
</Echo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
有两种方法可以解决此问题.骇客程度最低,几乎是您想要的东西:
There are a couple of ways to solve this. The least hackiest and almost what you want:
$client = new SoapClient(
null,
array(
'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler',
'uri' => 'http://example.com/wsdl',
'trace' => 1,
'use' => SOAP_LITERAL,
)
);
$params = new \SoapVar("<Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer>", XSD_ANYXML);
$result = $client->Echo($params);
这将为您提供以下XML:
This gets you the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl">
<SOAP-ENV:Body>
<ns1:Echo>
<Acquirer>
<Id>MyId</Id>
<UserId>MyUserId</UserId>
<Password>MyPassword</Password>
</Acquirer>
</ns1:Echo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
几乎就是您想要的,除了方法名称上的名称空间.我不知道这是不是一个问题.如果是这样,您甚至可以进一步破解它.您可以手动将<Echo>
标记放入XML字符串中,并让SoapClient不通过将'style' => SOAP_DOCUMENT,
添加到options数组中来设置方法,如下所示:
That is almost exactly what you want, except for the namespace on the method name. I don't know if this is a problem. If so, you can hack it even further. You could put the <Echo>
tag in the XML string by hand and have the SoapClient not set the method by adding 'style' => SOAP_DOCUMENT,
to the options array like this:
$client = new SoapClient(
null,
array(
'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler',
'uri' => 'http://example.com/wsdl',
'trace' => 1,
'use' => SOAP_LITERAL,
'style' => SOAP_DOCUMENT,
)
);
$params = new \SoapVar("<Echo><Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer></Echo>", XSD_ANYXML);
$result = $client->MethodNameIsIgnored($params);
这将导致以下请求XML:
This results in the following request XML:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<Echo>
<Acquirer>
<Id>MyId</Id>
<UserId>MyUserId</UserId>
<Password>MyPassword</Password>
</Acquirer>
</Echo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
最后,如果您想使用SoapVar和SoapParam对象,可以在PHP手册的此注释中找到一个很好的参考:
Finally, if you want to play around with SoapVar and SoapParam objects, you can find a good reference in this comment in the PHP manual: http://www.php.net/manual/en/soapvar.soapvar.php#104065. If you get that to work, please let me know, I failed miserably.