由输出缓冲截断的PHP Web服务消息

时间:2014-10-29 12:31:05

标签: php web-services soap output-buffering

我正在开发PHP上的Web服务,我使用标准的PHP SoapServer类和我的客户端提供的WSDL文件,但我还需要使用输出缓冲来“整理”PHP生成的SOAP响应(添加一些缺少的名称空间,将xmlns=""添加到一些标签和其他小但必要的细节。) 问题是,当我使用显式输出缓冲(ob_start()ob_end_flush() ...)时,来自我的服务器的任何出站消息都会被截断,无论其大小如何(我在大约2KB的范围内进行测试) -50KB)。当我不使用显式输出缓冲时,客户端获得完整的SOAP响应,但由于我提到的那些细节尚未修复,格式不太正确。
这是我服务器的代码:

if (!extension_loaded("soap")) {
    dl("php_soap.dll");
}

//Disable wsdl caching
ini_set("soap.wsdl_cache_enabled", "0");

//Get SOAP message from client
$input_msg = file_get_contents("php://input");

//Create SoapServer object with url to the .wsdl file
$server = new SoapServer(WSDL_FILE_URL, array('encoding' => 'UTF-8', 'actor' => SERVER_URL));

//Set the class that will handle every possible request form the client
$server->setClass("ServerHandler",$input_msg);

//Before I let the server handle the request and return the response to the client,
//I turn on output buffering so I can fix its format
ob_start(NULL, 1<<20);
$server->handle(); //let the server handle the request and write the response to the buffer
$soapXml = ob_get_contents(); //I get the response from the output buffer
ob_end_clean(); //clear the output buffer of its content

//this function does all those small format fixes to the SOAP response that PHP produces
$soapXml=fixSoapResponseFormat($soapXml);

echo $soapXml;//put the correct SOAP response in the output buffer
ob_end_flush();//flush the output buffer and turn off buffering
flush();//this supossedly flushes lower level buffers, just in case

正如您所看到的,我尝试使用$chunk_size ob_start()参数的高值,并在flush()之后添加ob_end_flush(),以防万一。我也尝试在php.ini上设置output_buffering = On(据说可以启用无限制的输出缓冲区),并在Apache上将LimitRequestFieldSizeLimitRequestLine设置为5500000,但无济于事。
我已经尝试在刷新缓冲区之后将$soapXml的内容转储到磁盘上,并且消息已经完成,所以我猜问题必须在echo $soapXml;行或者在刷新缓冲区之后它。
我正在使用Apache和PHP 5.3运行服务器而SoapUI 5作为客户端来测试它。我还在服务器和客户端之间的所有通信中使用WS-Security(如果它是相关的)。

有没有人知道如何通过缓冲SOAP消息来解决这个问题?也许还有另一种方法来捕获和修改PHP在发送到客户端之前产生的SOAP响应?我很感激任何建议。

1 个答案:

答案 0 :(得分:2)

显然,问题是我让PHP在$server->handle();行中生成带有http标头的SOAP消息,但后来我在缓冲区中捕获它并更改其大小而不更新{ {1}} http标头,因此邮件已发送,但被截断为原始大小 所以这是正确工作的代码:

Content-Length

非常感谢Valentin Rodygin帮助我找到麻烦的来源!