【问题标题】:PHP SoapClient __call() exception: DTD are not supported by SOAPPHP SoapClient __call() 异常:SOAP 不支持 DTD
【发布时间】:2011-06-16 16:23:11
【问题描述】:

这个杀了我……

我目前正在学习用 PHP 开发 SOAP 服务器,但遇到了一个烦人的问题,尽管在相关问题上获得了很多成功,但 Google 并没有提供太多帮助...

在使用我认为很好的 WSDL 实例化 SOAP CLIENT 之后,对肥皂服务器上现有函数的第一次调用会生成以下异常:

SoapFault Object
(
    [message:protected] => DTD are not supported by SOAP
    [string:private] => 
    [code:protected] => 0
    [file:protected] => /var/www/soapserver/soapServerTestClient.php
    [line:protected] => 7
    [trace:private] => Array
        (
            [0] => Array
                (
                    [function] => __call
                    [class] => SoapClient
                    [type] => ->
                    [args] => Array
                        (
                            [0] => testSoapService
                            [1] => Array
                                (
                                    [0] => TESTSTRING
                                )

                        )

                )

            [1] => Array
                (
                    [file] => /var/www/soapserver/soapServerTestClient.php
                    [line] => 7
                    [function] => testSoapService
                    [class] => SoapClient
                    [type] => ->
                    [args] => Array
                        (
                            [0] => TESTSTRING
                        )

                )

        )

    [faultstring] => DTD are not supported by SOAP
    [faultcode] => Client
    [faultcodens] => http://schemas.xmlsoap.org/soap/envelope/
)

转储 __getLastRequest()、__getLastResponse()、__getLastRequestHeaders() 和 __getLastResponseHeaders() 会产生完全空的结果,因此实际上没有发送/请求它。

访问 WSDL 的链接会按预期返回 WSDL 文件内容,我知道这是可行的,因为更改 WSDL 的路径会返回 SOAP-ERROR: Parsing WSDL: Couldn't load 异常,并将其放回实际的 WSDL 路径会生成上述异常。

soap 服务器代码如下,但由于没有请求/响应,我认为这不是问题:

函数 testSoapService($arg) { 返回 '​​'.$arg.''; }

ini_set("soap.wsdl_cache_enabled", "0"); // 禁用 WSDL 缓存,这样你 可以轻松测试 wsdl 更改; 设置 WSDL 时注释掉。 $服务器 = 新的肥皂服务器(“”); $server->addFunction("testSoapService"); $server->handle();

搜索 google,很多人都说它要么是错误的 wsdl 路径(在这种情况下不这么认为),要么是服务器从网络服务器,我也不认为是这种情况,因为请求/响应是空的。

这是 WSDL 内容的副本,以防万一:

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:types>

    <schema xmlns:rns="http://soap.jrimer-amp64/" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soap.jrimer-amp64/" version="1.0" elementFormDefault="unqualified" attributeFormDefault="unqualified">
        <complexType name="testSoapServiceRequest">
            <sequence>
                <element name="testKey" type="string"/>
            </sequence>
        </complexType>
        <complexType name="testSoapServiceResponse">
            <sequence>
                <element name="result" type="string" minOccurs="1"/>
                <element name="retStatus" type="rns:returnStatus"/>
            </sequence>
        </complexType>
        <complexType name="returnStatus">
            <sequence>
                <element name="errorMessage" type="string" minOccurs="0"/>
                <element name="errorCode" type="string" minOccurs="0"/>
            </sequence>
            <attribute name="success" type="boolean"/>
        </complexType>
        <element name="addRouterToCustomerAccountRequest" type="rns:addRouterToCustomerAccountRequest"/>
        <element name="addRouterToCustomerAccountResponse" type="rns:addRouterToCustomerAccountResponse"/>
    </schema>

</wsdl:types>


<wsdl:service name="XxxxxxSvc">

    <wsdl:port name="XxxxxxSvc-Endpoint0" binding="tns:XxxxxxSvc-Endpoint0Binding">
        <soap:address location="http://soap.jrimer-amp64"/>
    </wsdl:port>

</wsdl:service>


<wsdl:portType name="portType">

    <wsdl:operation name="testSoapService">
        <wsdl:input message="tns:testSoapServiceRequest"/>
        <wsdl:output message="tns:testSoapServiceResponse"/>
    </wsdl:operation>

</wsdl:portType>


<wsdl:binding name="XxxxxxSvc-Endpoint0Binding" type="tns:portType">

    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="testSoapService">
        <soap:operation style="document" soapAction="http://soap.jrimer-amp64/XxxxxxSvc-SoapServer.php"/>
        <wsdl:input>
            <soap:body use="literal" parts="parameters"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal" parts="parameters"/>
        </wsdl:output>
    </wsdl:operation>

</wsdl:binding>


<wsdl:message name="testSoapServiceRequest">
    <wsdl:part name="parameters" element="ns0:testSoapServiceRequest"/>
</wsdl:message>


<wsdl:message name="testSoapServiceResponse">
    <wsdl:part name="parameters" element="ns0:testSoapServiceResponse"/>
</wsdl:message>

有什么想法吗?

【问题讨论】:

  • 用浏览器访问 WSDL 时看到了什么?

标签: php soap wsdl soap-client


【解决方案1】:

转储 __getLastRequest(), __getLastResponse()、__getLastRequestHeaders() 和 __getLastResponseHeaders() 产生完全空的结果,所以没有 实际上正在发送/请求它 出现。

您是否使用设置为truetrace 选项设置您的客户端?您需要在 dumpLastXXX 方法起作用之前执行此操作。

【讨论】:

  • 你摇滚得那么厉害,我可以通过网络感受到它。我的服务 URL 一定是错误的,因为它不是指向服务器代码,而是指向同一路径的 index.php 代码......感谢您的帮助! ...为了更清楚,设置跟踪允许我看到请求和响应的内容,当跟踪设置为 true 时,它​​们不再是空值!
  • 不客气 :-)。顺便说一句,请注意 PHP SOAP 服务器实现充其量是错误的,它只是可用,但要为问题做好准备。这是我在 SOAP 服务器上工作时遇到的一个:bugs.php.net/bug.php?id=49169
猜你喜欢
  • 2021-02-28
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多