SOAP:看起来我们没有XML文档。

15

我正在尝试创建一个Web服务,但在此之前,我想先尝试让我在互联网上找到的一个简单示例正常运行,但我一直收到以下错误:

Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in C:\Documents and Settings\geoff\My Documents\Websites\jquery\index.php:20 Stack trace: #0 [internal function]: SoapClient->__call('getStockQuote', Array) #1 C:\Documents and Settings\geoff\My Documents\Websites\jquery\index.php(20): SoapClient->getStockQuote(Array) #2 {main} thrown in C:\Documents and Settings\geoff\My Documents\Websites\jquery\index.php on line 20

我正在使用nusoap v1.94

我的Web服务代码如下:

function getStockQuote($symbol) {
$price = '1.23';
return $price;
}

require('nusoap.php');

$server = new soap_server();

$server->configureWSDL('stockserver', 'urn:stockquote');

$server->register("getStockQuote",
            array('symbol' => 'xsd:string'),
            array('return' => 'xsd:decimal'),
            'urn:stockquote',
            'urn:stockquote#getStockQuote');

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)
                  ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);

我知道一个造成这个问题的原因是在服务器脚本中的php标记之前或之后有空格,但这不是问题所在。这个问题已经让我疯狂了好几个小时!非常感谢任何帮助。

11个回答

7
一个字节顺序标记(BOM)与php标签之前的空格具有相同的效果。您可以在这里找到一个PHP片段来检测和删除BOM。请确保配置您的编辑器不再插入BOM。

6
很晚了,但我还是想分享我的解决方法以便其他人受益。当我将Apache服务器从2.2升级到2.4和PHP 5.4.10升级到5.6.18时,在Windows上出现了类似的错误。客户端应用程序使用的是php 5.6.1。为了解决这个问题,我做了以下几点:
  1. 向SoapClient传递SOAP版本参数:

    'soap_version' => SOAP_1_1

  2. 在服务器php.ini配置文件中添加:

    always_populate_raw_post_data = -1


4

在php.ini文件中设置always_populate_raw_post_data = -1(通过删除;),然后重启服务器。对我来说这很有效。


4
有点晚了,但这种错误通常是由服务器端(SOAP意义上)问题引起的:
  • 打印/输出内容
  • rik的回答也是如此
  • 错误(例如,我当前遇到了这个错误,因为在include中有一个拼写错误,导致生成include错误而不是执行脚本...)
  • SOAP服务器中的错误参数
  • 双方压缩级别不同(如果使用压缩)
这条消息只是告诉您SOAP客户端没有接收到格式良好的XML(例如,收到的是错误消息而不是XML)。

3
该错误还会出现在 SOAP XML 响应中包含特殊的 Unicode 字符时。在我的情况下,它是 REPLACEMENT CHARACTER (U+FFFD)。
具体来说,SoapClient 的内部函数 xmlParseDocument 在解析后将 xmlParserCtxtPtr->wellFormed 属性设置为 false。它会抛出带有 looks like we got no XML document 的 soap 错误。 https://github.com/php/php-src/blob/master/ext/soap/php_packet_soap.c#L46

2
据我所知,当SOAP解析器遇到无效的XML时会出现错误。
就像我的情况一样。
  1. 打开错误显示
  2. 在try-catch中执行,并在catch中调用__getLastResponse
  3. 我捕获了另一个错误:

警告:simplexml_load_string():实体:第1行:解析器错误: xmlParseCharRef:无效的xmlChar值26 in

  1. 最初使用的是PHP5.3。一旦在PHP5.4上运行脚本,错误信息变得更加详细-我发誓有一个无效字符,这可能是导致SOAP解析器崩溃的原因。
结果,我得到了以下代码:
$params = array(...);
try
{
    $response = $client->method( $params );
}
catch(SoapFault $e)
{
    $response = $client->__getLastResponse();
    $response = str_replace("&#x1A",'',$response); ///My Invalid Symbol
    $response = str_ireplace(array('SOAP-ENV:','SOAP:'),'',$response);
    $response = simplexml_load_string($response);
}

如果有人在评论中解释一下这个符号的含义,我将不胜感激。

这个问题可能是关于 https://dev59.com/rHrZa4cB1Zd3GeqP46bv 的吗? - Erenor Paz
__getLastResponse() 帮助我识别了无效字符。 - subroutines

1
当我与加载模型的Magento API进行交互时,我收到了这个错误,并且在输出XML响应之前它会抛出一个警告,从而导致了这个错误。
要解决这个问题,您可以简单地关闭API函数上的警告:error_reporting(0);

API函数位于哪里? - Bob Flemming
无论你调用的是哪个API函数,如果它是你自己的自定义API函数,请将其放在那里;如果不是你自己的函数,你需要进行调试以找到它。 - Kus

1
多年过去了,我想分享一个对某些人有用的经验;我的情况是在SAOP响应体中返回了一个单元分隔符字符,导致XML无效。因此,我需要扩展SoapClient(另一个答案的建议)并从响应中删除0x1f字符,如下所示:
class SoapClientNoBOM extends SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        // strip away everything but the xml (including removal of BOM)
        $response = preg_replace('#^.*(<\?xml.*>)[^>]*$#s', '$1', $response);
        // also remove unit separator
        $response = str_replace("\x1f", '', $response);
        return $response;
    }
}

现在使用SoapClientNoBOM来实例化一个SOAP客户端,而不是使用本地的SoapClient。


0

另一种可能的解决方案是...

我遇到了相同的问题,把我搞疯了。解决方法很简单。 验证我的服务器,因为这是一个服务器错误。 我的错误是我把 "rcp" 写成了 "rpc"。


0

尝试查看您的服务器日志。如果您使用nginx,请查看/var/log/nginx/error.log。 如果出现“权限被拒绝”的提示,请更改相关目录所有者。 希望能解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接