Я разрабатываю веб-службу на PHP, где я использую стандартный класс PHP SoapServer с WSDL-файлом, предоставленным моим клиентом, но мне также нужно использовать буферизацию вывода для «убирать», ответ SOAP, который генерирует PHP (добавление некоторых отсутствующих пространств имен, добавление xmlns=""
к нескольким тегам и другим небольшим, но необходимым деталям).
Проблема заключается в том, что когда я использую явную буферизацию вывода (ob_start()
, ob_end_flush()
...), любое исходящее сообщение с моего сервера обрезается, независимо от его размера (я тестирую в диапазоне около 2 КБ-50 КБ). Когда я не использую явную буферизацию вывода, клиент получает полный ответ SOAP, но поскольку те данные, о которых я упоминал, не были исправлены, формат не совсем прав.
Вот код моего сервера:Сообщения веб-службы PHP, усеченные буферизацией вывода
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
Как вы можете видеть, я попытался использовать высокое значение для параметра ob_start()
$chunk_size
и добавление 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, прежде чем он будет отправлен клиенту? Я был бы благодарен за любой совет.
Где вы выписываете $ soapXml? Право на браузер? Или это приложение CLI? –
Я выводил «прямо в браузер», так сказать, но это действительно клиентская программа (SoapUI). Моя серверная программа получает запрос SOAP от клиента через http и возвращает ответ через http. Этот ответ - результат, с которым у меня возникают проблемы. –
Возможно, браузер неправильно отображает xml-теги, и вы не избегаете их. Вы сказали, что успешно свалили документ на диск. Вы пытались открыть исходный код страницы? –