如何从这个xml在php中生成一个soap请求?

时间:2012-05-07 23:26:00

标签: php xml soap request

我厌倦了尝试使用SOAP发送请求。这是我的xml

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:bpf="http://schemas.datacontract.org/2004/07/Bpf.Security.Common" xmlns:bpf1="http://schemas.datacontract.org/2004/07/Bpf.Security.Authentication.Common">
         <soapenv:Header>
 <InfoTag xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/BaufestProductivityFramework">
  <ClientIp xmlns="http://schemas.datacontract.org/2004/07/Bpf.Common.Service">200.125.145.10</ClientIp> 
  <CompanyId xmlns="http://schemas.datacontract.org/2004/07/Bpf.Common.Service">1</CompanyId>
  <UserName xmlns="http://schemas.datacontract.org/2004/07/Bpf.Common.Service">someUser</UserName> 
  </InfoTag>
        </soapenv:Header>
           <soapenv:Body>
              <tem:LogIn>         
                <tem:token>
                    <bpf:type>
                       <bpf1:Description>someDesc</bpf1:Description>
                       <bpf1:Id>1</bpf1:Id>
                       <bpf1:Name>someDesc</bpf1:Name>
                    </bpf:type>
                    <bpf:password>somePass</bpf:password>
                    <bpf:userName>someUser</bpf:userName>
                </tem:token>
              </tem:LogIn>
           </soapenv:Body>
        </soapenv:Envelope>

这个函数发送带有命名空间的标题,但是有多个...我必须全部发送它们?

 private function __getHeaders() {
            $ns = 'http://schemas.xmlsoap.org/soap/envelope/'; //Namespace of the WS. 
            $ip = $_SERVER['REMOTE_ADDR'];
    //Body of the Soap Header. 
            $headerbody = array('ClientIp' => $ip,
                                'CompanyId' => 1, 
                                'UserName' => 'someUser'
                                );

    //Create Soap Header.        
            $header = new SOAPHeader($ns, 'InfoTag', $headerbody);
            return $header;
        }

    public function prepareWs(){
    $wsdl="the web service";
           $client = new SoapClient($wsdl, array('trace' => true));
    //Set the Headers of Soap Client. 
           $header = $this->__getHeaders();
           $client->__setSoapHeaders($header);

我尝试发送这个主体,我检查了soap的异常,但是消息只返回“bad request NULL NULL NULL”。

$params = new stdClass();  
      $params = new SoapVar("<tem:token>
        <bpf:type xmlns:bpf="http://schemas.datacontract.org/2004/07/Bpf.Security.Common">
           <bpf1:Description xmlns:bpf1="http://schemas.datacontract.org/2004/07/Bpf.Security.Authentication.Common">someDesc</bpf1:Description>
           <bpf1:Id xmlns:bpf1="http://schemas.datacontract.org/2004/07/Bpf.Security.Authentication.Common">1</bpf1:Id>
           <bpf1:Name xmlns:bpf1="http://schemas.datacontract.org/2004/07/Bpf.Security.Authentication.Common">someName</bpf1:Name>
        </bpf:type>
        <bpf:password xmlns:bpf="http://schemas.datacontract.org/2004/07/Bpf.Security.Common">somePass</bpf:password>
        <bpf:userName xmlns:bpf="http://schemas.datacontract.org/2004/07/Bpf.Security.Common">someUser</bpf:userName>
    </tem:token>", XSD_ANYXML);

       $response = $client->Login($params);

}

使用CURL,我可以发送此XML并收到XML响应,但是使用SOAPClient我无法发送此请求。

我希望有人可以帮助我,谢谢。

这是我用firebug看到的代码,我唯一得到的是“糟糕的请求”。当我使用__getLastRequest()时,我看到了同样的...... 我想不应该正确发送标题,但__setSoapHeaders函数返回true。 这是输出:

<soap-env:envelope xmlns:ns1="http://tempuri.org/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:header>
<soap-env:contextinformation>
<item>
<key>ClientIp</key>
<value>127.0.0.1</value>
</item>
<item>
<key>CompanyId</key>
<value>1</value>
</item>
<item>
<key>UserName</key>
<value>someUser</value>
</item>
</soap-env:contextinformation>
</soap-env:header>
<soap-env:body>
<tem:login>
<tem:token>
<bpf:type>
<bpf1:description>someDesc</bpf1:description>
<bpf1:id>1</bpf1:id>
<bpf1:name>someName</bpf1:name>
</bpf:type>
<bpf:password>somePass</bpf:password>
<bpf:username>someUser</bpf:username>
</tem:token>
</tem:login>
</soap-env:body>
</soap-env:envelope>

1 个答案:

答案 0 :(得分:2)

SoapHeader相当对待数组。如果您想使用数组,请考虑使用ArrayObject instead of the native construct

但是,您根本不需要数组,因为您只是尝试在标题中构造单个元素。并且因为每个内部元素(例如 ClientIP )都具有唯一的命名空间,所以您不能只传入基本对象。相反,您必须使用SoapVar类为每个元素指定一个特定的命名空间,这允许您将正常的PHP数据包装在SoapClient可以理解和翻译的“SOAP-ready”容器中。 p>

$innerNS = "http://www.w3.org/BaufestProductivityFramework";
$outerNS = "http://schemas.datacontract.org/2004/07/Bpf.Common.Service";

$tag = new stdClass();
$tag->ClientIP = new SoapVar("200.125.145.10", XSD_STRING, null, null, null, $innerNS);
$tag->CompanyId = new SoapVar(1, XSD_INT, null, null, null, $innerNS);
$tag->UserName = new SoapVar("someUser", XSD_STRING, null, null, null, $innerNS);

$client->__setSoapHeaders(new SoapHeader($outerNS, 'InfoTag', $tag));

最后,作为一项规则,不要手动编写XML!考虑重写您的SOAP正文代码,如此处所示的标题代码。您应该能够专门处理XML的内容,而不是其结构。