Сообщения веб-службы PHP, усеченные путем буферизации вывода

Я занимаюсь разработкой веб-службы на PHP, в которой я использую стандартный класс PHP SoapServer с файлом WSDL, предоставленным моим клиентом, но мне также нужно использовать буферизацию вывода, чтобы «привести в порядок» ответ SOAP, который генерирует PHP (добавив некоторые недостающие пространства имен , добавив xmlns="" на несколько тегов и других мелких, но необходимых деталей).
Проблема в том, что когда я использую явную буферизацию вывода (ob_start(), ob_end_flush() …) любое исходящее сообщение с моего сервера усекается независимо от его размера (я тестирую в диапазоне от 2 до 50 КБ). Когда я не использую явную буферизацию вывода, клиент получает полный ответ 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(), так, на всякий случай. Я также пытался установить output_buffering = On на php.ini (который якобы включает неограниченный выходной буфер) и настройки LimitRequestFieldSize а также LimitRequestLine до 5500000 на Apache, но безрезультатно.
Я пытался сбросить на диск содержимое $soapXml после очистки буфера, и сообщение завершено, поэтому я думаю, что проблема должна быть в echo $soapXml; линия или в очистке буфера сразу после него.
Я использую Apache с PHP 5.3 для запуска сервера и SoapUI 5 в качестве клиента для его тестирования. Я также использую WS-Security во всех коммуникациях между сервером и клиентом (в случае необходимости).

Кто-нибудь знает, как решить эту проблему с буферизацией SOAP-сообщений? Может быть, есть другой способ перехватить и изменить ответ SOAP, который генерирует PHP перед отправкой клиенту? Буду благодарен за любой совет.

0

Решение

Очевидно, проблема заключалась в том, что я позволял PHP генерировать SOAP-сообщение с его заголовком http в $server->handle(); линии, но потом я записывал его в буфер и изменение его размера без обновления Content-Length заголовок http, поэтому сообщение было отправлено, но урезано до его первоначального размера.
Итак, вот правильно работающий код:

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);

header('Content-Length: '.strlen($soapXml));//**UPDATE THE LENGTH HEADER**

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

Большое спасибо Валентину Родыгину за его огромную помощь в поиске источника моих неприятностей!

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]