2013-05-29 70 views
10

我試圖實現在SAP PI系統上運行的Web服務。我得到的WSDL看起來是這樣的:PHP SoapClient:未知所需WSDL擴展

<?xml version="1.0" encoding="UTF-8"?> 
<wsdl:definitions name="request_SO" targetNamespace="http://company.ch/orstest/jason_test" xmlns:p1="http://company.ch/orstest/jason_test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:documentation/> 
    <wsp:UsingPolicy wsdl:required="true"/> 
    <wsp:Policy wsu:Id="OP_request_SO"/> 
    <wsdl:types> 
     <xsd:schema targetNamespace="http://company.ch/orstest/jason_test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://company.ch/orstest/jason_test"> 
      <xsd:element name="request" type="request"/> 
      <xsd:element name="response" type="response"/> 
      <xsd:complexType name="request"> 
       <xsd:annotation> 
        <xsd:appinfo source="http://sap.com/xi/VersionID">a8b7948ac2e211e2b2380000001f0d6a</xsd:appinfo> 
       </xsd:annotation> 
       <xsd:sequence> 
        <xsd:element name="body" type="xsd:string"/> 
       </xsd:sequence> 
      </xsd:complexType> 
      <xsd:complexType name="response"> 
       <xsd:annotation> 
        <xsd:appinfo source="http://sap.com/xi/VersionID">bf49af09c36c11e299790000001f0d6a</xsd:appinfo> 
       </xsd:annotation> 
       <xsd:sequence> 
        <xsd:element name="body" type="xsd:string"/> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:schema> 
    </wsdl:types> 
    <wsdl:message name="request"> 
     <wsdl:documentation/> 
     <wsdl:part name="request" element="p1:request"/> 
    </wsdl:message> 
    <wsdl:message name="response"> 
     <wsdl:documentation/> 
     <wsdl:part name="response" element="p1:response"/> 
    </wsdl:message> 
    <wsdl:portType name="request_SO"> 
     <wsdl:documentation/> 
     <wsdl:operation name="request_SO"> 
      <wsdl:documentation/> 
      <wsp:Policy> 
       <wsp:PolicyReference URI="#OP_request_SO"/> 
      </wsp:Policy> 
      <wsdl:input message="p1:request"/> 
      <wsdl:output message="p1:response"/> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="request_SOBinding" type="p1:request_SO"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     <wsdl:operation name="request_SO"> 
      <soap:operation soapAction="http://sap.com/xi/WebService/soap1.1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
      <wsdl:input> 
       <soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="request_SOService"> 
     <wsdl:port name="HTTP_Port" binding="p1:request_SOBinding"> 
      <soap:address location="http://qa1100ap601.company.car.web:50000/XISOAPAdapter/MessageServlet?senderParty=&amp;senderService=BS_ORS&amp;receiverParty=&amp;receiverService=&amp;interface=request_SO&amp;interfaceNamespace=http://company.ch/orstest/jason_test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     </wsdl:port> 
     <wsdl:port name="HTTPS_Port" binding="p1:request_SOBinding"> 
      <soap:address location="https://qas.soa.subcompany.company.ch/XISOAPAdapter/MessageServlet?senderParty=&amp;senderService=BS_ORS&amp;receiverParty=&amp;receiverService=&amp;interface=request_SO&amp;interfaceNamespace=http://company.ch/orstest/jason_test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

我的PHP文件看起來像這樣(沒有更多的它目前):

<?php 
$client = new SoapClient('test.wsdl'); 
?> 

當我跑步時我的劇本,我拋出了以下錯誤:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Unknown required WSDL extension 'http://schemas.xmlsoap.org/ws/2004/09/policy' in /srv/www/htdocs/wsdl.php:2 Stack trace: #0 /srv/www/htdocs/wsdl.php(2): SoapClient->SoapClient('test.wsdl') #1 {main} thrown in /srv/www/htdocs/wsdl.php on line 2 

我試圖尋找谷歌和StackOverflow上的錯誤,並且還檢查php.net的意見,但我似乎無法找出我不得不爲了得到這種改變服務運行。我也嘗試打開W​​SDL擴展URL,它似乎存在。

有人可以在這裏扔骨頭嗎?我試圖消除擴展URL,這會導致以下錯誤:

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Unexpected WSDL element <UsingPolicy> in /srv/www/htdocs/wsdl.php:2 Stack trace: #0 /srv/www/htdocs/wsdl.php(2): SoapClient->SoapClient('test.wsdl') #1 {main} thrown in /srv/www/htdocs/wsdl.php on line 2 

回答

16

我能想到的,在這一點上是更新您的UsingPolicy標籤的唯一解決辦法:

更改標籤:

<wsp:UsingPolicy wsdl:required="true"/> 

這樣:

<wsp:UsingPolicy wsdl:required="false"/> 
+2

嘿,太棒了,現在錯誤消失了:)現在我可以嘗試服務:) – Ahatius

+0

太棒了!很高興幫助。 –

14

這是不是真的在SAP環境中的正確答案。在WSDL的URL中,您將看到/ws_policy/ - 將其更改爲/standard/,您將能夠使用PHP SoapClient類來使用Web服務,而無需維護本地修改的WSDL副本。您可以在SAP博客here上看到相同的內容(可能需要登錄)。

+0

我的SAP網絡服務正是這個問題,您的答案拯救了我的一天! – Shmarkus

3

For new versions the URL is not containing anymore the "ws_policy" instead there is a 0 (standard)or 1 (policy)

Example:

....wsdl/flv_10002A111AD1/bndg_url/.... (ws_policy)

....wsdl/flv_10002A101AD1/bndg_url/.... (standard)

Rafa Martinez

+0

謝謝你這個偉大的答案!你救了我幾個小時! – Sonson123

0

似乎是在PHP SoapServer時的錯誤,或缺少擴展兼容性,還尚未得到解決,至少在PHP 31年6月5日。

我能找到的唯一解決辦法是設定要求UsingPolicyfalse,如建議在接受響應:

<wsp:UsingPolicy wsdl:required="false" /> 

但是客戶端可以訪問,而無需身份驗證的SOAP服務,這是一個嚴重的安全問題。所以,我試圖手動檢查安全數據是由客戶端發送的。

$soapEnvelope = new DOMDocument(); 
$soapEnvelope->loadXML(file_get_contents("php://input"), LIBXML_DTDATTR); 
$wsseNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 

if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Security')->length == 0) { 
    throw new SoapFault("auth", 'Authentication error - Missing wsse:Security node'); 
} 

if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'UsernameToken')->length == 0) { 
    throw new SoapFault("auth", 'Authentication error - Missing UsernameToken node'); 
} 

if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Username')->length == 0) { 
    throw new SoapFault("auth", 'Authentication error - Missing Username node'); 
} 

if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Password')->length == 0) { 
    throw new SoapFault("auth", 'Authentication error - Missing Password node'); 
} 

// SOAPServer handle requests method 
$server->handle(); 

這是一個骯髒的把戲,但它的作品。