7

所以错误是:

PHP Fatal error: Procedure 'sup:set_availability' not present in XMLSoapServer.php

我在我的开发环境 (MAMP) 上收到此错误。

这是由无效的 XML 字符串引起的,其中未定义“sup”命名空间:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <sup:set_availability>
            <SetAvailability>
                ...
            </SetAvailability>
        </sup:set_availability>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

(这是一个外部请求,所以我不能只是去纠正来源 - 我可以,但至少不是在短时间内。)

问题是我有 2 台服务器正在处理相同的请求。没有错误。所以我的任务是找出原因:)

一些细节:

  • 服务器 1:php 5.3.2
  • 服务器 2:php 5.4
  • 开发:php 5.4

到目前为止我检查过的事情:

  • 代码是相同的 svn-checkout
  • 没有隐藏的开发或生产设置
  • apache配置是一样的
  • wsdl 缓存被禁用,缓存的 wsdl 被清除
  • php.ini 设置相同,但 libxml2 除外:

服务器 1 的版本为 2.6.26 服务器 2 的版本为 2.7.7 - 请求在该版本上的工作就像一个魅力 我的开发环境有 lixml2 版本 2.8.0 - 并且确实引发了致命错误。

我的猜测是(或者曾经是)libxml2 导致了错误——但我找不到关于这个主题的任何资源——我也没有成功地将我的本地 libxml2 版本降级到 2.6 或 2.7。

所以......对此有什么想法吗?

4

4 回答 4

2

我认为缺少传递给soap客户端的变量。检查soap客户端是否工作

于 2014-05-07T06:49:22.270 回答
2

我会建议一个不同的角度来解决这个问题。

您可以在将请求提供给 XML 解析器之前修改请求,而不是破坏您的 XML 解析器。sup如果名称空间不存在,则将其添加到请求中。最好将此更改推送到生产并更新/修复您的生产 XML 解析器。

一旦外部来源使他们的软件正常工作,请删除此 hack。

于 2014-05-10T20:09:56.763 回答
2

我不知道问题是什么......但由于原生 PHP SoapClient 对我来说总是有点“不透明”,我喜欢使用Dklab_SoapClient 库

它使用 Curl 来检索 Soap 数据,它比原生 PHP 类灵活得多。另外,如果您也需要,您甚至可以扩展它以添加您自己的功能:) 我猜它会解决您的问题。

但是,如果您不想使用外部库,我不知道是什么导致了这种情况......

于 2014-05-05T15:58:33.667 回答
0

这听起来像是服务器配置的问题。WSDL URI 对于您的开发机器可能是错误的,因此当soapserver 对WSDL 进行自省时,它无法找到该函数,因为它正在查找错误的服务器。

XML 虽然仍然是错误的,因为名称空间前缀仍未定义。我不希望它安全地工作,因为这不是有效的 XML,并且 SOAP 工作需要有效的 XML。

使用 LIBXML 2.9.1 进行的快速测试显示,错误的 XML 块在加载时DOMDocument带有警告但被保留(包括前缀)。如果您可以访问底层请求文档,则可以自己添加:

// just test code to mock a DOMDocument having the fault XML from question
$doc  = new DOMDocument();
$back = libxml_use_internal_errors(TRUE);
$doc->loadXML($xml);
libxml_use_internal_errors($back);

// poc to add the prefix definition
$doc->documentElement->setAttributeNS(
    'http://www.w3.org/2000/xmlns/', 'xmlns:sup', 'sup:uri'
);

那么文件是:

<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" 
        xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:sup="sup:uri">
    <SOAP-ENV:Body>
        <sup:set_availability>
            <SetAvailability>
                ...
            </SetAvailability>
        </sup:set_availability>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如您所见,已添加前缀定义。您可以在之前拦截传入的请求SoapServer::handle(),将其更改并注入handle($soap_request)

  • 肥皂动作:$_SERVER['HTTP_SOAPACTION']
  • 请求正文:file_get_contents( 'php://input')
  • 看:SoapServer::handle()
于 2014-05-11T19:04:12.747 回答