我正在开发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上将LimitRequestFieldSize
和LimitRequestLine
设置为5500000,但无济于事。
我已经尝试在刷新缓冲区之后将$soapXml
的内容转储到磁盘上,并且消息已经完成,所以我猜问题必须在echo $soapXml;
行或者在刷新缓冲区之后它。
我正在使用Apache和PHP 5.3运行服务器而SoapUI 5作为客户端来测试它。我还在服务器和客户端之间的所有通信中使用WS-Security(如果它是相关的)。
有没有人知道如何通过缓冲SOAP消息来解决这个问题?也许还有另一种方法来捕获和修改PHP在发送到客户端之前产生的SOAP响应?我很感激任何建议。
答案 0 :(得分:2)
显然,问题是我让PHP在$server->handle();
行中生成带有http标头的SOAP消息,但后来我在缓冲区中捕获它并更改其大小而不更新{ {1}} http标头,因此邮件已发送,但被截断为原始大小
所以这是正确工作的代码:
Content-Length
非常感谢Valentin Rodygin帮助我找到麻烦的来源!