如何构造复杂的嵌套soap参数

时间:2014-01-15 23:29:19

标签: php soap

好吧,这个问题让我陷入困境。我没有成功尝试使用PHP和SOAP连接到Web服务。我无法弄清楚什么是错的,更重要的是这是一项全新的服务,他们的“文档”是不好的。所以我不知道问题实际上是不是在他们的结尾,但我没有足够的经验使用SOAP能够确切知道。我祈祷有人可以帮助我。

我已经能够通过将XML直接放入SOAP UI来连接到服务,但每当我尝试使用SoapClient时,它就会崩溃。我希望发送的XML结构看起来像

<Envelope xmlns:ns1="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://a.uri" xmlns:ns3="http://tempuri.org/">
 <Body>
    <GetAuthorization>
        <ns1:registrationObj ns1:type="ns2:RegistrationAuthorization">
            <ns2:Company>####</ns2:Company>
            <ns2:Computer>####</ns2:Computer>
            <ns2:Facility>####</ns2:Facility>
        </ns1:registrationObj> 
    </GetAuthorization>
</Body>
</Envelope>

我尝试了太多无法列出的方法。使用__soapCall和$ client-&gt; method(),SoapVar和SoapParam。总的来说,我发现PHP的SoapClient的文档有点稀疏。但是我甚至无法获得调用的结构以匹配我想要的内容(通过__getLastRequest()转储)

我注意到的一件事是客户端不断删除我的数组的第一个元素(当我尝试将参数作为普通数组传递时,在那些实例上。所以:

$params = array("Company" => "abc",
                "Computer" => "def",
                "Facility" => "ghi");
$result = $soap_client->__soapCall('GetAuthorization',$params);

返回

<env:Body>
    <ns1:GetAuthorization/>
    <param1>def</param1>
    <param2>ghi</param2>
</env:Body>

请注意,在这个实例中,GetAuthorization自闭合并删除了第一个数组元素。我也分别经历了(并且值得注意的是,我已经让参数也被正确命名。我已经经历了如此多的迭代,我不记得什么尝试产生了哪些结果。但是,SOAP不是表现得像我期望它。它无法正确封装数据和/或丢弃随机元素。

$parameters = 
array("ra" => new SoapVar(array(
    "CompanyId" => new SoapVar("####", SOAP_ENC_OBJECT, 'guid', 'http://schemas.microsoft.com/2003/10/Serialization/', 'CompanyId', 'http://schemas.datacontract.org/x/y/z.xx'),
    "ComputerId" => new SoapVar("{####}", SOAP_ENC_OBJECT, 'string', 'http://www.w3.org/2001/XMLSchema', 'ComputerId', 'http://schemas.datacontract.org/x/y/z.xx'),
    "FacilityId" => new SoapVar("####", SOAP_ENC_OBJECT, 'guid', 'http://schemas.microsoft.com/2003/10/Serialization/', 'FacilityId', 'http://schemas.datacontract.org/x/y/z.xx')
), SOAP_ENC_OBJECT, 'RegistrationAuthorization', 'http://schemas.datacontract.org/x/y/z.xx', 'ra', "http://schemas.datacontract.org/x/y/z.xx"

)));

$result = $auth_client->GetAuthorization($parameters);

我试图通过最初的结构(在我简化之前试图弄清楚出了什么问题之前),认为因为我需要对参数的命名空间进行如此多的控制。但这只是使用自闭元素发出请求。

有人可以告诉我如何构建调用以产生适当的XML结构吗?是否可能这是在服务端,WSDL有问题? (我不确定WSDL在后端究竟应该负责什么。)

我为这个问题的模糊性道歉,但我感到很失落,我甚至不确定要问的是对的。 : - (

2 个答案:

答案 0 :(得分:3)

应该有效:

<?php
$client = new \SoapClient(null, array(
    'uri'           => 'http://localhost/stack/21150482/',
    'location'      => 'http://localhost/stack/21150482/server.php',
    'trace'         => true
));
try {

    $company         = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Company', 'http://a.uri');
    $computer        = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Computer', 'http://a.uri');
    $facility        = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Facility', 'http://a.uri');

    $registrationObj = new \SoapVar(
        array($company,$computer,$facility),
        SOAP_ENC_OBJECT,
        'RegistrationAuthorization',
        'http://a.uri',
        'registrationObj',
        'http://www.w3.org/2001/XMLSchema-instance'
    );

    $client->GetAuthorization($registrationObj);

} catch (\Exception $e) {
    var_dump($e->getMessage());
}

$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($client->__getLastRequest());

print '<pre>';
print htmlspecialchars($dom->saveXML());

我的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/stack/21150482/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://a.uri" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:GetAuthorization>
      <xsi:registrationObj xsi:type="ns2:RegistrationAuthorization">
        <ns2:Company xsi:type="xsd:string">XXXXX</ns2:Company>
        <ns2:Computer xsi:type="xsd:string">XXXXX</ns2:Computer>
        <ns2:Facility xsi:type="xsd:string">XXXXX</ns2:Facility>
      </xsi:registrationObj>
    </ns1:GetAuthorization>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

答案 1 :(得分:0)

我使用的不同方法是:

<?php 

//note the "(object)" casting
$params = (object)[
  'registrationObj' => (object)[
    'Company' => 'abc',
    'Computer' => 'def',
    'Facility' => 'ghi'
  ]
];

$soap_client = new SoapClient('localhost/soap');

//direct call of the method GetAuthorization (without __soapCall)
$return = $soap_client->GetAuthorization($params);

适用于PHP&gt; = 5.4