Исключение SoapFault: Ошибка [HTTP] При извлечении http-заголовков
Я получаю следующее исключение на своей странице php.
Исключение SoapFault: Ошибка [HTTP] При извлечении http-заголовков
Я прочитал пару статей и обнаружил, что default_socket_timeout нуждается в настройке. поэтому я поставил его следующим образом. default_socket_timeout = 480
Я все еще получаю ту же ошибку. Кто-нибудь может мне помочь?
3 answers
Я получаю Error fetching http headers
по двум причинам:
- Серверу требуется много времени, чтобы ответить.
- Сервер не поддерживает
Keep-Alive
соединения (которые охватывает мой ответ).
PHP всегда будет пытаться использовать постоянное соединение с веб-службой, отправляя HTTP-заголовок Connection: Keep-Alive
. Если сервер всегда закрывает соединение и не сделал этого (PHP не получил EOF
), вы можете получить Error fetching http headers
, когда PHP попытается повторно использовать соединение, которое уже закрыто на стороне сервера.
Примечание: этот сценарий произойдет только в том случае, если один и тот же объект SoapClient
отправляет более одного запроса и с высокой частотой. Отправка Connection: close
HTTP-заголовка вместе с первым запросом исправила бы это.
В PHP версии 5.3.5 (в настоящее время поставляется с Ubuntu) настройка заголовка HTTP Connection: Close
не поддерживается SoapClient. Нужно иметь возможность отправлять HTTP-заголовок в контексте потока (используя $option
- ключ stream_context
в качестве аргумента SoapClient
), но SoapClient
не поддерживает изменение заголовка подключения ( Обновление: Эта ошибка была решена в PHP версии 5.3.11).
Другое решение состоит в том, чтобы реализовать свой собственный __doRequest()
. По предоставленной ссылке парень использует Curl
для отправки запроса. Это сделает ваше PHP-приложение зависимым от Curl
. В реализации также отсутствуют такие функции, как сохранение заголовков запросов/ответов.
Третье решение - просто закрыть соединение сразу после ответ получен. Это можно сделать, установив атрибут SoapClients httpsocket
в NULL
в __doRequest()
, __call()
или __soapCall()
. Пример с __call()
:
class MySoapClient extends SoapClient {
function __call ($function_name , $arguments) {
$response = parent::__call ($function_name , $arguments);
$this->httpsocket = NULL;
return $response;
}
}
У меня была та же проблема, и я попробовал следующее, отключив keep_alive
.
$api_proxy = new SoapClient($api_url, array('trace' => true, 'keep_alive' => false));
Однако у меня это не сработало. Что сработало, сработало для меня, так это отключение кэша SOAP. Похоже, что он кэшировал неправильные запросы, и после отключения я действительно заметил, что мои запросы выполнялись быстрее.
На сервере Linux вы можете найти это в своем файле /etc/php.ini
.
Найдите soap.wsdl_cache_enabled=1
и измените его на soap.wsdl_cache_enabled=0
.
Не забудьте перезагрузить apache.
service httpd reload
Выполнение одного из моих процессов в веб-службе занимало много времени. Поэтому я получал отказ от исполнения по умолчанию.