PHP SoapClient正文参数未被发送

时间:2016-04-25 19:47:36

标签: php soap soap-client

我正在尝试使用PHP中的SoapClient进行SOAP调用,但是我在发送body参数时遇到了问题。正好发送标题并且没有错误但是正文是空的。

我对PHP不太熟悉所以这对我来说是新的。

这是我的登录功能:

function Login($username, $password, $clientaccesskey, $useraccesskey)
{
    $parameters = array(
                    'LogOnRequest' => 
                            array(
                                'ClientAccessKey' => $clientaccesskey,
                                'Password' => $password,
                                'UserAccessKey' => $useraccesskey,
                                'UserName' => $username
                                )
                     );

    $headers = array();

    $headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'Action', 'http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn');
    $headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'To', 'https://service4.ultipro.com/services/BiDataService');

    try 
    {
        $soapclient = new SoapClient('https://service4.ultipro.com/services/BiDataService', array('soap_version' => SOAP_1_2, 'encoding' => 'UTF-8', 'exceptions' => TRUE, 'trace' => TRUE));
        $soapclient->__setSoapHeaders($headers);
        $response = $soapclient->__soapCall('LogOn', array($parameters));

        echo json_encode($response);

        echo htmlentities($soapclient->__getLastRequest());
    }
    catch(SoapFault $fault){
        echo $fault->faultstring;
    }

}

当我运行此代码时,它似乎正在与服务器通信,因为我收到了回复:

{"LogOnResult":{"ServiceId":null,"ClientAccessKey":null,"Token":null,"Status":"Failed","StatusMessage":"User authentication failed","InstanceKey":null}}

但这是发送给服务的XML:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.ultipro.com/dataservices/bidata/2" xmlns:ns2="http://www.w3.org/2005/08/addressing">
   <env:Header>
      <ns2:Action>http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</ns2:Action>
      <ns2:To>https://service4.ultipro.com/services/BiDataService</ns2:To>
   </env:Header>
   <env:Body>
      <ns1:LogOn />
   </env:Body>
</env:Envelope>

这就是支持XML的样子:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <a:Action s:mustUnderstand="1">http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</a:Action>
      <a:To s:mustUnderstand="1">https://servicehost/services/BiDataService</a:To>
   </s:Header>
   <s:Body>
      <LogOn xmlns="http://www.ultipro.com/dataservices/bidata/2">
         <logOnRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <UserName>username</UserName>
            <Password>password</Password>
            <ClientAccessKey>12345</ClientAccessKey>
            <UserAccessKey>01234567890</UserAccessKey>
         </logOnRequest>
      </LogOn>
   </s:Body>
</s:Envelope>

我做错了导致在SOAP请求中不发送body参数?

1 个答案:

答案 0 :(得分:3)

我能够使用类SOAPVarSOAPParam类来实现它,如下所示:

function Login($username, $password, $clientaccesskey, $useraccesskey)
{
    // Class handler for the request
    class LogOnRequest {
        function __construct($usr, $pwd, $cak, $uak)
        {
            $this->UserName = $usr;
            $this->Password = $pwd;
            $this->ClientAccessKey = $cak;
            $this->UserAccessKey = $uak;
        }
    }

    // Conversion to a SOAP object
    $lor = new LogOnRequest($username, $password, $clientaccesskey, $useraccesskey);
    $logOnRequest = new SoapVar($lor, SOAP_ENC_OBJECT, 'LogOnRequest', 'http://soapinterop.org/xsd');

    $headers = array();
    $headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'Action', 'http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn');
    $headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'To', 'https://service4.ultipro.com/services/BiDataService');

    try 
    {
        $soapclient = new SoapClient('https://service4.ultipro.com/services/BiDataService', array('soap_version' => SOAP_1_2, 'encoding' => 'UTF-8', 'exceptions' => TRUE, 'trace' => TRUE));
        $soapclient->__setSoapHeaders($headers);

        // Direct call to the LogOn method and SOAP parameter pass
        $response = $soapclient->LogOn(new SoapParam($logOnRequest, 'logOnRequest'));

        echo json_encode($response);

        echo htmlentities($soapclient->__getLastRequest());
    }
    catch(SoapFault $fault){
        echo $fault->faultstring;
    }

}

这给了我以下XML请求:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.ultipro.com/dataservices/bidata/2" xmlns:ns3="http://www.w3.org/2005/08/addressing">
    <env:Header>
        <ns3:Action>http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</ns3:Action>
        <ns3:To>https://service4.ultipro.com/services/BiDataService</ns3:To>
    </env:Header>
    <env:Body>
        <ns2:LogOn xsi:type="ns1:LogOnRequest">
            <UserName>u</UserName>
            <Password>p</Password>
            <ClientAccessKey>cak</ClientAccessKey>
            <UserAccessKey>uak</UserAccessKey>
        </ns2:LogOn>
    </env:Body>
</env:Envelope>