如何使用 PHP SoapClient 添加任意命名空间?

发布于 2024-11-09 11:42:06 字数 6563 浏览 6 评论 0 原文

如何使用 PHP SoapClient 添加任意名称空间?命名空间实际上并未在请求中使用,但我认为它阻止了我的消息被正确使用。

WSDL 位于:http://abr.business.gov.au/abrxmlsearchRPC/ ABRXMLSearch.asmx?WSDL

我要发送的特定消息的文档位于此处:http://abr.business.gov.au/abrxmlsearchRPC/(nye2ok45xc42vy552b15dx3t)/FormGenerator/ABRSearchByNameSimpleProtocol.aspx。我正在执行 SOAP 请求。

在soap:Envelope 中,您会注意到一个名为xmlns:types="http://abr.business.gov.au/ABRXMLSearchRPC/encodedTypes" 的命名空间,并且您还会注意到soap:Body 中未使用它。

我发送的消息是:(为了可读性而添加了换行符和缩进,为了安全性而对authenticationGuid进行了混淆)

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:ABRSearchByNameSimpleProtocol>
            <name xsi:type="xsd:string">company</name>
            <postcode xsi:type="xsd:string"></postcode>
            <legalName xsi:type="xsd:string">Y</legalName>
            <tradingName xsi:type="xsd:string">Y</tradingName>
            <NSW xsi:type="xsd:string">Y</NSW>
            <SA xsi:type="xsd:string">Y</SA>
            <ACT xsi:type="xsd:string">Y</ACT>
            <VIC xsi:type="xsd:string">Y</VIC>
            <WA xsi:type="xsd:string">Y</WA>
            <NT xsi:type="xsd:string">Y</NT>
            <QLD xsi:type="xsd:string">Y</QLD>
            <TAS xsi:type="xsd:string">Y</TAS>
            <authenticationGuid xsi:type="xsd:string">aaaa</authenticationGuid>
        </ns1:ABRSearchByNameSimpleProtocol>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我得到的响应是:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:types="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">    
        <types:ABRSearchByNameSimpleProtocolResponse><ABRSearchByNameSimpleProtocolResult href="#id1" /></types:ABRSearchByNameSimpleProtocolResponse>
        <types:Payload id="id1" xsi:type="types:Payload">
            <Request href="#id2" />
            <Response href="#id3" />
        </types:Payload>
        <types:ExternalRequest id="id2" xsi:type="types:ExternalRequest">           
            <ExternalRequestBody href="#id4" />
        </types:ExternalRequest>
        <types:Response id="id3" xsi:type="types:Response">
            <DateRegisterLastUpdated xsi:type="xsd:dateTime">0001-01-01T00:00:00.0000000+11:00</DateRegisterLastUpdated>
            <DateTimeRetrieved xsi:type="xsd:dateTime">2011-05-26T09:31:06.2949724+10:00</DateTimeRetrieved>
            <ResponseBody href="#id5" />
        </types:Response>
        <types:ExternalRequestNameSearch id="id4" xsi:type="types:ExternalRequestNameSearch">
            <AuthenticationGUID xsi:type="xsd:string" />
            <Name xsi:type="xsd:string" />
            <Filters href="#id6" />
        </types:ExternalRequestNameSearch>
        <types:ResponseException id="id5" xsi:type="types:ResponseException">
            <ExceptionDescription xsi:type="xsd:string">The GUID entered is not recognised as a Registered Party.

 Search GUID: </ExceptionDescription>
            <ExceptionCode xsi:type="xsd:string">WebServices</ExceptionCode>  
        </types:ResponseException>
        <types:ExternalRequestFilters id="id6" xsi:type="types:ExternalRequestFilters">
            <NameType href="#id7" />
            <Postcode xsi:type="xsd:string" />
            <StateCode href="#id8" />
        </types:ExternalRequestFilters>
        <types:ExternalRequestFilterNameType id="id7" xsi:type="types:ExternalRequestFilterNameType">
            <TradingName xsi:type="xsd:string">Y</TradingName>
            <LegalName xsi:type="xsd:string">Y</LegalName>
        </types:ExternalRequestFilterNameType>
        <types:ExternalRequestFilterStateCode id="id8" xsi:type="types:ExternalRequestFilterStateCode">
            <QLD xsi:type="xsd:string">Y</QLD>
            <NT xsi:type="xsd:string">Y</NT>
            <SA xsi:type="xsd:string">Y</SA>
            <WA xsi:type="xsd:string">Y</WA>
            <VIC xsi:type="xsd:string">Y</VIC>
            <ACT xsi:type="xsd:string">Y</ACT>
            <TAS xsi:type="xsd:string">Y</TAS>
            <NSW xsi:type="xsd:string">Y</NSW>
        </types:ExternalRequestFilterStateCode>
    </soap:Body>
</soap:Envelope>

看起来消费者已经完全忽略了消息的内容。我可以看到示例中唯一缺少的是类型命名空间,它包含在响应中。

因此,我认为如果我可以任意将类型命名空间添加到请求中,可能会有更好的运气。

如果有人能告诉我如何做到这一点,或者提供一些其他建议,说明为什么消费者会忽略我在请求中给出的值,我将不胜感激。

更新:扩展 SoapClient 并覆盖 __doRequest() 以添加命名空间实际上可能是解决方案,但我希望得到更了解的人的确认。应该注意的是,SoapClient::getLastRequest() 的内容是在 __doRequest() 进行修改之前生成的,因此通过 __doRequest() 进行的任何修改可能需要通过 tcp 转储来观察。

示例代码是

class ABRSoapClient extends SoapClient {

    function __doRequest($request, $location, $action, $version) {
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->preserveWhiteSpace = false;
        $dom->loadXML($request);

        $dom->documentElement->setAttribute
        ('xmlns:types', 'http://abr.business.gov.au/ABRXMLSearchRPC/encodedTypes');

        $request = $dom->saveXML();

        error_log('Request in class:'.$request);

        return parent::__doRequest($request, $location, $action, $version);
    }
}

How does one add an arbitrary namespace using PHP SoapClient? The namespace does not actually get used in the request, but I think it is preventing my message from being properly consumed.

The WSDL is here : http://abr.business.gov.au/abrxmlsearchRPC/ABRXMLSearch.asmx?WSDL

The documentation for the particular message I want to send is here : http://abr.business.gov.au/abrxmlsearchRPC/(nye2ok45xc42vy552b15dx3t)/FormGenerator/ABRSearchByNameSimpleProtocol.aspx. I'm doing the SOAP request.

In the soap:Envelope, you'll notice a namespace called xmlns:types="http://abr.business.gov.au/ABRXMLSearchRPC/encodedTypes", and you'll also notice it's not used in the soap:Body.

The message I'm sending is : (newlines and indenting added for readability, authenticationGuid obfuscated for security)

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:ABRSearchByNameSimpleProtocol>
            <name xsi:type="xsd:string">company</name>
            <postcode xsi:type="xsd:string"></postcode>
            <legalName xsi:type="xsd:string">Y</legalName>
            <tradingName xsi:type="xsd:string">Y</tradingName>
            <NSW xsi:type="xsd:string">Y</NSW>
            <SA xsi:type="xsd:string">Y</SA>
            <ACT xsi:type="xsd:string">Y</ACT>
            <VIC xsi:type="xsd:string">Y</VIC>
            <WA xsi:type="xsd:string">Y</WA>
            <NT xsi:type="xsd:string">Y</NT>
            <QLD xsi:type="xsd:string">Y</QLD>
            <TAS xsi:type="xsd:string">Y</TAS>
            <authenticationGuid xsi:type="xsd:string">aaaa</authenticationGuid>
        </ns1:ABRSearchByNameSimpleProtocol>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The response I get back is :

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:types="http://abr.business.gov.au/ABRXMLSearchRPC/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">    
        <types:ABRSearchByNameSimpleProtocolResponse><ABRSearchByNameSimpleProtocolResult href="#id1" /></types:ABRSearchByNameSimpleProtocolResponse>
        <types:Payload id="id1" xsi:type="types:Payload">
            <Request href="#id2" />
            <Response href="#id3" />
        </types:Payload>
        <types:ExternalRequest id="id2" xsi:type="types:ExternalRequest">           
            <ExternalRequestBody href="#id4" />
        </types:ExternalRequest>
        <types:Response id="id3" xsi:type="types:Response">
            <DateRegisterLastUpdated xsi:type="xsd:dateTime">0001-01-01T00:00:00.0000000+11:00</DateRegisterLastUpdated>
            <DateTimeRetrieved xsi:type="xsd:dateTime">2011-05-26T09:31:06.2949724+10:00</DateTimeRetrieved>
            <ResponseBody href="#id5" />
        </types:Response>
        <types:ExternalRequestNameSearch id="id4" xsi:type="types:ExternalRequestNameSearch">
            <AuthenticationGUID xsi:type="xsd:string" />
            <Name xsi:type="xsd:string" />
            <Filters href="#id6" />
        </types:ExternalRequestNameSearch>
        <types:ResponseException id="id5" xsi:type="types:ResponseException">
            <ExceptionDescription xsi:type="xsd:string">The GUID entered is not recognised as a Registered Party.

 Search GUID: </ExceptionDescription>
            <ExceptionCode xsi:type="xsd:string">WebServices</ExceptionCode>  
        </types:ResponseException>
        <types:ExternalRequestFilters id="id6" xsi:type="types:ExternalRequestFilters">
            <NameType href="#id7" />
            <Postcode xsi:type="xsd:string" />
            <StateCode href="#id8" />
        </types:ExternalRequestFilters>
        <types:ExternalRequestFilterNameType id="id7" xsi:type="types:ExternalRequestFilterNameType">
            <TradingName xsi:type="xsd:string">Y</TradingName>
            <LegalName xsi:type="xsd:string">Y</LegalName>
        </types:ExternalRequestFilterNameType>
        <types:ExternalRequestFilterStateCode id="id8" xsi:type="types:ExternalRequestFilterStateCode">
            <QLD xsi:type="xsd:string">Y</QLD>
            <NT xsi:type="xsd:string">Y</NT>
            <SA xsi:type="xsd:string">Y</SA>
            <WA xsi:type="xsd:string">Y</WA>
            <VIC xsi:type="xsd:string">Y</VIC>
            <ACT xsi:type="xsd:string">Y</ACT>
            <TAS xsi:type="xsd:string">Y</TAS>
            <NSW xsi:type="xsd:string">Y</NSW>
        </types:ExternalRequestFilterStateCode>
    </soap:Body>
</soap:Envelope>

It looks like the consumer has completely disregarded the content of the message. The only thing I can see that is missing from the example is the types namespace, which is included in the response.

Thus, I'm thinking that if I can arbitrarily add the types namespace to the request, it may have better luck.

If anyone could tell me how to do that, or offer some other suggestion why the consumer ignores the values I've given in the request, that would be greatly appreciated.

Update: Extending SoapClient and overriding __doRequest() to add the namespace might actually be the solution, but I'd like a confirmation from someone who knows better. It should be noted that the content of SoapClient::getLastRequest() is generated before modifications made by __doRequest(), so any modifications made via __doRequest() may need to be observed via a tcp dump.

Example code for this is

class ABRSoapClient extends SoapClient {

    function __doRequest($request, $location, $action, $version) {
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->preserveWhiteSpace = false;
        $dom->loadXML($request);

        $dom->documentElement->setAttribute
        ('xmlns:types', 'http://abr.business.gov.au/ABRXMLSearchRPC/encodedTypes');

        $request = $dom->saveXML();

        error_log('Request in class:'.$request);

        return parent::__doRequest($request, $location, $action, $version);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文