Я разрабатываю веб-службу на 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, прежде чем он будет отправлен клиенту? Буду благодарен за любой совет.
$soapXml
) на диск на сервере, что означает, что данные предположительно завершены до того, как они будут записаны в выходной буфер, по крайней мере. - person Miguel A. Romero   schedule 29.10.2014$soapXml=fixSoapResponseFormat($soapXml);
, сообщение будет отправлено правильно. Однако, если я оставлю эту строку, сообщение будет отправлено усеченным, но если я сброшу его на диск на сервере сразу после отправки, оно будет завершено и правильно измененоfixSoapResponseFormat()
! Эта функция состоит из цикла, в котором я делаю ряд замен в сообщении с помощью$soapXml=str_replace($original_tag, $replacement_tag, $soapXml);
. Я всегда заменяю целые теги XML их более полными эквивалентами, чтобы избежать нежелательных замен. - person Miguel A. Romero   schedule 29.10.2014$server->handle();
, и когда я вызвалfixSoapResponseFormat()
, сообщение стало больше, но я не обновил данные о размере в заголовке. Я опубликую рабочий код в качестве ответа, чтобы люди могли легко его найти. Спасибо большое за то, что наставили меня на правильный путь, Валентин! Что я могу сделать, чтобы улучшить вашу репутацию? (Я новичок на этом сайте) - person Miguel A. Romero   schedule 29.10.2014