Я пытаюсь вызвать WS over https на удаленном хосте: удаленный порт, и я получаю:
Ошибка получения заголовков HTTP
используя PHP5 SoapClient; Я могу получить список функций, выполнив $client->__getFunctions()
но когда я вызываю $client->myFunction(...)
я всегда получаю эту ошибку.
Я googled и нашел, чтобы увеличить default_socket_timeout в php.ini, но это не сработало.
Может ли кто-нибудь предложить мне решение?
EDIT: вот код:
$wsdl="myWSDL"; $client = new SoapClient($wsdl,array('connection_timeout'=>5,'trace'=>true,'soap_version'=>SOAP_1_2)); var_dump($client->__getFunctions()); try { $response=$client->myFunction("1","2","3"); } catch (SoapFault $fault) { var_dump($fault); }
}
… всегда виноват.
Эта ошибка часто возникает, когда значение default_socket_timeout
превышено для ответа SOAP. ( См. Эту ссылку .)
Примечание от конструктора SoapClient: параметр connection_timeout
используется для определения значения тайм-аута для подключения к службе, а не для таймаута для его ответа.
Вы можете увеличить его так:
ini_set('default_socket_timeout', 600); // or whatever new value you want
Имейте в виду, что вы не должны использовать это как постоянное решение , а скорее, чтобы устранить эту ошибку, прежде чем перейти к исследованию, почему служба SOAP так медленно реагирует. Если услуга последовательно медленная, вам может потребоваться автономная / пакетная обработка.
Просто хотел поделиться решением этой проблемы в моей конкретной ситуации (у меня были одинаковые симптомы). В моем сценарии оказалось, что сертификат ssl, предоставляемый веб-службой, больше не доверяет. Фактически это было связано с новым брандмауэром, который был установлен клиентом, который мешал запросу SOAP, но конечным результатом было то, что сертификат не был правильно обслуживан / доверен.
Было немного сложно отследить, потому что вызов SoapClient (даже с трассировкой = 1) не дает очень полезной обратной связи.
Я смог доказать ненадежный сертификат, используя:
openssl s_client -connect <web service host>:<port>
Я знаю, что это не будет ответом на все проблемы, но, надеюсь, это помогает кому-то. В любом случае, я думаю, что важно понять, что причина этой ошибки (ошибка: «HTTP» faultstring: «Error Fetching http headers») обычно будет проблемой сети / сокета / протокола / связи, а не просто «недостаточно времени для запроса ». Я не могу себе представить, что расширение значения default_socket_timeout позволит решить эту проблему очень часто, и даже если это произойдет, наверняка было бы лучше решить вопрос о том, почему это так медленно в первую очередь.
Я полагаю, что уже слишком поздно, но у меня такая же проблема. Я пробую тайм-аут сокета, но он не работает. Моя проблема заключалась в том, что клиент и сервер, на том же физическом сервере. Когда клиентский код работает на одном и том же физическом сервере, я получаю эту ошибку, но с тем же кодом клиента, который переместился на мой локальный хост, запросив сервер (клиент и сервер были выполнены в двух разных мечках), все работает нормально.
Может быть, это может помочь кому-то другому!
Я просто хотел добавить, для полноты, что похоже на Manachi, я получил это сообщение, потому что сертификат клиента, который я использовал, требовал ключевой фразы, и у меня случайно был дополнительный символ в конце фразы. Это сообщение просто для того, чтобы предложить еще одно предложение для изучения. Если хост требует использования сертификата клиента (через параметр local_cert), убедитесь, что вы указали правильный путь к сертификату и правильную кодовую фразу (если необходимо). Если вы этого не сделаете, очень вероятно, что вы увидите это же сообщение об ошибке.
Ни один из вышеперечисленных методов не работал для меня.
Когда я проанализировал заголовок запроса из __getLastRequestHeaders, я увидел следующее:
POST /index.php/api/index/index/?SID=012345 HTTP/1.1 Host: www.XYZ.com
URL-адрес API, который я использовал, был другим, например, http://www.ABC.com. Я изменил URL-адрес API на http://www.XYZ.com/index.php/api?wsdl, а затем он сработал.
Оба URL-адреса вернули один и тот же WSDL с одного и того же сервера, но только один разрешенный вход в систему.
У меня была эта проблема, и я проверил, и в моем случае был брандмауэр. PHP неправильно показывает ошибку. Чтобы выполнить запрос, брандмауэр ответил:
HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 ... <html ... <h1>Direct Access IP is not allowed</h1> ... </html>
SoapClient ожидает конверт SOAP, но получает HTML-код. Вот почему PHP отвечает: «Ошибка получения заголовков Http», потому что он не может понять, что он получил в ответ. Чтобы устранить эту проблему, обратитесь к сетевому администратору, чтобы проверить, нет ли какого-либо брандмауэра, NAT или прокси-сервера, а затем попросить их принять необходимые меры.
Проверьте HTTP-заголовок ответа. В моем случае на API-сайте был установлен следующий заголовок:
<IfModule mod_headers.c> Header set Connection keep-alive </IfModule>
Кажется, что PHP SoapClient не может справиться с этим вариантом. В результате тело ответа было пустым, но длина содержимого в заголовке ответа была установлена правильно.
Удалите эту строку или измените ее, чтобы «закрыть» решить мою проблему.
У меня была такая же проблема, и я попробовал следующее, отключив 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
Конфигурация, которая работала для меня, определяла на моем php-скрипте следующие параметры:
ini_set('default_socket_timeout', 5000); $client = new \SoapClient($url,array( 'trace' =>true, 'connection_timeout' => 5000, 'cache_wsdl' => WSDL_CACHE_NONE, 'keep_alive' => false, ));
Прокомментируйте, пожалуйста.
Наиболее важным параметрическим определением, согласно моему опыту с этой проблемой, было
ini_set('default_socket_timeout', 5000);
Во время моих тестов я определил значение default_socket_timeout до 5 секунд, и ошибка «Ошибочная выборка заголовков HTTP» была поднята мгновенно.
Надеюсь, это поможет!