Ответ 1
Проблема решена. Проблема заключается в кеше
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
Иногда не удается вызвать веб-службу.
Эта проблема происходит все время.
В чем может быть проблема?
Error:
SoapFault exception: [HTTP] Could not connect to host in
0 [internal function]: SoapClient->__doRequest('<?xml version="...', http://.', '', 1, 0)
Проблема решена. Проблема заключается в кеше
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
Я добавляю свой комментарий для полноты, поскольку перечисленные здесь решения не помогли мне. На PHP 5.6 SoapClient делает первый вызов указанного URL WSDL в SoapClient::SoapClient
, а после подключения к нему и получения результата он пытается подключиться к WSDL, указанному в результате:
<soap:address location="http://"/>
И вызов завершается с ошибкой Could not connect to host
, если WSDL отличается от той, которую вы указали в SoapClient::SoapClient
, и недоступен (мой случай был SoapUI, используя http://host.local/).
Поведение в PHP 5.4 отличается и оно всегда использует WSDL в SoapClient::SoapClient
.
Хост либо работает, либо очень медленно реагирует. Если он медленно реагирует, вы можете попытаться увеличить время ожидания с помощью параметра connection_timeout
или с помощью параметра default_socket_timeout
и посмотреть, уменьшает ли это ошибки.
http://www.php.net/manual/en/soapclient.soapclient.php
http://www.php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout
Вы также можете включить обработку ошибок, поскольку zanlok указал на повторную попытку несколько раз. Если у вас есть пользователи, которые действительно ждут этих SOAP-вызовов, вам нужно будет поставить их в очередь и обработать их в фоновом режиме и уведомить пользователя, когда они будут завершены.
в файле php.ini, который управляет кэшем доступа wsdl, есть раздел конфигурации soap, может отображаться как:
[soap]
; Enables or disables WSDL caching feature.
soap.wsdl_cache_enabled=1 ;
Sets the directory name where SOAP extension will put cache files.
soap.wsdl_cache_dir="/tmp"
; (time to live) Sets the number of second while cached file will be used ; instead of original one.
soap.wsdl_cache_ttl=86400
Если кеш файл wsdl включен, это может вызвать эту проблему при изменении URI wsdl в php-коде.
в этом примере вы можете просто удалить начало файла с помощью wsdl-
в директории /tmp
.
или вы просто установите soap.wsdl_cache_enabled=0;
и soap.wsdl_cache_ttl=0;
PHP будет получать файл wsdl каждый раз, когда вы посещаете страницу.
неправильно настроенный сервис оставляет пространство имен по умолчанию с tempuri.org
Это означает, что соединение с wsdl будет работать, но вызов функции не удастся.
Stacktrace:
SoapClient->__doRequest('http://example.com...', 'http://tempuri.org....', 2, 0)
Чтобы исправить это, вы должны явно указать местоположение, используя __setLocation()
$this->soapClient = new \SoapClient(WS_URL);
$this->soapClient->__setLocation(WS_URL);
Я сам попал в эту проблему, и после долгого рытья я в конце концов нашел эту ошибку для ubuntu:
https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371
в частности
https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371/comments/62
openssl s_client -connect site.tld:443
не удалось, однако openssl s_client -tls1 -connect site.tld:443
дал успех. В моем частном случае часть результата включала
New, TLSv1/SSLv3, Cipher is RC4-MD5
, поэтому я правильно установил значение ssl/cipher для php-контекста.
В нашем случае это была проблема переговоров с шифрами. Мы получили эту ошибку случайно. Мы решили нашу проблему с помощью шифра следующим образом:
$soapClient = new SoapClient('http://example.com/soap.asmx?wsdl',array("stream_context" => stream_context_create(array('ssl' => array('ciphers'=>'AES256-SHA')))));
Похоже, PHP не согласовывал одни и те же шифры при каждом вызове службы.
В моем случае он работал после подключения к wsdl, используйте функцию __setLocation()
, чтобы определить местоположение снова, потому что вызов завершился с ошибкой:
Не удалось подключиться к хосту
Это происходит, если WSDL отличается от указанного в SoapClient::SoapClient
.
Кажется, что ошибка SoapFault exception: Could not connect to host
может быть вызвана несколькими разными вещами. В моем случае это не было вызвано прокси-сервером, брандмауэром или DNS (у меня на самом деле было соединение SOAP с той же машины, что и с помощью nusoap без любая специальная настройка).
Наконец, я обнаружил, что это было вызвано недопустимым pem
файлом, на который я ссылался в опции local_cert
в моем конструкторе SoapClient.
Решение:
Когда я удалил цепочку сертификатов из файла pem
, поэтому только содержал сертификат и закрытый ключ, вызовы SOAP начали проходить.
Это работа для меня
$opts = array(
'ssl' => array('verify_peer' => false, 'verify_peer_name' => false)
);
if (!isset($this->soap_client)) {
$this->soap_client = new SoapClient($this->WSDL, array(
'soap_version' => $this->soap_version,
'location' => $this->URL,
'trace' => 1,
'exceptions' => 0,
'stream_context' => stream_context_create($opts)
));
Наконец-то я нашел причину, потому что ее библиотека не может найти набор СА в вашей системе. PHP >= v5.6 автоматически устанавливает verify_peer в true по умолчанию. Однако не все системы имеют известный набор СА на диске.
Вы можете попробовать одну из следующих процедур:
1.Если у вас есть файл CA в вашей системе, установите openssl.cafile
или curl.cainfo
в свой php.ini
путь к вашему файлу CA.
2.Установите свое местоположение файла CA CA
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($cHandler, CURLOPT_CAINFO, $path-of-your-ca-file);
3.disabled verify_peer
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Для меня это проблема DNS. Мои серверы имен VPS исчезли, поэтому я переключился на Google, отредактировав файл /etc/resolv.conf следующим образом: сервер имен 8.8.8.8 nameserver 8.8.4.4
Если у вас есть брандмауэр на вашем сервере, обязательно откройте порт, используемый SOAP.
В моем случае мне пришлось открыть порт 1664.
iptables -t filter -A INPUT -p tcp --dport 1664 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 1664 -j ACCEPT
Если решение ujava не может вам помочь, вы можете попробовать использовать try/catch, чтобы поймать этот фатальный, это отлично работает на меня.
try{
$res = $client->__call('LineStopQueryJson',array('Parameters' => $params));
}catch(SoapFault $e){
print_r($client);
}
В моем случае служебный адрес в wsdl неверен.
Мой wsdl url.
https://myweb.com:4460/xxx_webservices/services/ABC.ABC?wsdl
Но адрес службы в этом xml-результате.
<soap:address location="http://myweb.com:8080/xxx_webservices/services/ABC.ABC/"/>
Я просто сохраняю этот xml в локальном файле и меняю адрес службы на.
<soap:address location="https://myweb.com:4460/xxx_webservices/services/ABC.ABC/"/>
Удачи.
Со мной эта проблема в базовом адресе в app.config службы WCF: Когда я использовал:
<baseAddresses><add baseAddress="http://127.0.0.1:9022/Service/GatewayService"/> </baseAddresses>
это нормально, если вы используете .net для подключения к общедоступному ip или домену.
Но когда вы используете PHP SoapClient для подключения к "http://[online ip]:9022/Service/GatewayService
", он генерирует исключение "Coulod not connect to host"
Я изменил baseAddress на [онлайн-ip]: 9022 и все нормально.
Для тех, кто так же, как и я, боролся с консольной командой laravel artisan, которая делает много запросов к одному и тому же wsdl внешнего мыльного сервера, а затем через некоторое время завершается с ошибкой Could not connect to host
error.
Проблема была в том, что я создавал новый экземпляр SoapClient
каждый раз перед тем, как был сделан запрос. Не делай этого. Создайте его один раз и сделайте каждый запрос от одного и того же клиента.
Надеюсь, поможет.
У меня была плохая конфигурация php.ini. Проверьте путь и срок действия сертификата...
[openssl]
openssl.cafile = "C:/good/phpath/ca-bundle.crt"
Поскольку мой новый \SoapClient ($ wsdl) был https!
Чтобы помочь другим людям, столкнувшимся с этой ошибкой, URL-адрес в <soap:address location="https://some.url"/>
имел недопустимый сертификат и вызвал ошибку.
Для меня это проблема в службе httpd
(Fedora 24). Простой перезапуск сделал трюк:
sudo service httpd restart
Если соединение через SSL, может быть проблема сервера, а не клиента (это мой случай).
В версиях PHP выше 5.6 и 7 важно проверить CipherSuite, используемый в сертификате сервера. Существует полный список шифров, разрешенных этими версиями, и полный список шифров, которых нет в данной веб-ссылке: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Ciphersuite.
Если используемый шифр недопустим (это устаревший алгоритм), SoapClient получает сообщение "Не удалось подключиться к хосту", и в нем больше нет следов.
Используемый шифр может быть проверен такими клиентами, как SoapUI, например, в разделе "Информация SSL".
В интернете нет ветки, посвященной этой теме.
Проверьте это тоже: http://php.net/manual/en/migration56.openssl.php
Для меня это была проблема с сертификатом. Следующее сработало у меня
$context = stream_context_create([
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]);
$client = new SoapClient(null, [
'location' => 'https://...',
'uri' => '...',
'stream_context' => $context
]);
Проверка версии помогла мне OpenSSL. OpenSSL_1_0_1f не поддерживается TSLv.1_2! Проверьте версию и совместимость с TSLv.1_2 на github openssl/openssl , И восстановите свой сертификат с новым openssl
openssl pkcs12 -in path.p12 -out newfile.pem
P.S. Я не знаю, в чем они были минус, но это решение действительно поможет.
Это скорее всего относится к проблеме подключения. Это может быть либо то, что ваше интернет-соединение было недоступно, либо веб-сервис, который вы пытаетесь использовать, был недоступен. Я предлагаю использовать эту услугу, чтобы узнать, находится ли веб-служба в сети или нет: http://downforeveryoneorjustme.com/