SOAP-ERROR: анализ WSDL: не удалось загрузить, но работает на WAMP
Это отлично работает на моем сервере WAMP, но не работает на главном сервере Linux!?
try{
$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]);
$result = $client->checkVat([
'countryCode' => 'DK',
'vatNumber' => '47458714'
]);
print_r($result);
}
catch(Exception $e){
echo $e->getMessage();
}
Что мне здесь пропало?!: (
SOAP включен
Ошибка
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl' : failed to load external entity "http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"/taxation_customs/vies/checkVatService.wsdl"
Вызов URL из PHP
Вызов URL-адреса из PHP возвращает ошибку
$wsdl = file_get_contents('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl');
echo $wsdl;
Ошибка
Warning: file_get_contents(http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl): failed to open stream: HTTP request failed! HTTP/1.0 503 Service Unavailable
Вызов URL из командной строки
Вызов URL-адреса из командной строки linux HTTP 200
возвращается с ответом XML
curl http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
Ответы
Ответ 1
Для некоторых версий php SoapClient не передает информацию HTTP-агента. Какие версии php у вас есть на сервере по сравнению с локальным WAMP?
Попробуйте явно установить пользовательский агент, используя поток контекста следующим образом:
try {
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$wsdlUrl = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl';
$soapClientOptions = array(
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
);
$client = new SoapClient($wsdlUrl, $soapClientOptions);
$checkVatParameters = array(
'countryCode' => 'DK',
'vatNumber' => '47458714'
);
$result = $client->checkVat($checkVatParameters);
print_r($result);
}
catch(Exception $e) {
echo $e->getMessage();
}
Изменить
На самом деле это некоторые проблемы с используемым веб-сервисом. Комбинация HTTP по протоколу IPv6 и отсутствующая строка HTTP User Agent, кажется, создает проблемы веб-службы.
Чтобы проверить это, попробуйте выполнить следующее на хосте linux:
curl -A '' -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
этот запрос IPv6 завершается с ошибкой.
curl -A 'cURL User Agent' -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
этот запрос IPv6 успешно завершен.
curl -A '' -4 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
curl -A 'cURL User Agent' -4 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
оба этих запроса IPv4 успешно завершены.
Интересный случай:) Я предполагаю, что ваш хост linux разрешает ec.europa.eu на свой IPv6-адрес и что ваша версия SoapClient по умолчанию не добавила строку пользовательского агента.
Ответ 2
Попробуй это. Надеюсь, это поможет
$options = [
'cache_wsdl' => 0,
'trace' => 1,
'stream_context' => stream_context_create(
[
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]
)
];
$client = new SoapClient($url, $options);
Ответ 3
Эта проблема может быть вызвана отключением загрузчика объектов libxml.
Попробуйте запустить libxml_disable_entity_loader(false);
перед созданием экземпляра SoapClient
.
Ответ 4
Попробуйте изменить
$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]);
к
$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY]);
Также (независимо от того, работает это или нет), убедитесь, что /tmp
можно записать на ваш веб-сервер и что он не заполнен.
Ответ 5
Это может быть полезно для кого-то, хотя нет точного ответа на этот вопрос.
Мой мыльный url имеет нестандартный порт (например, 9087), и брандмауэр заблокировал этот запрос, и я каждый раз принимал эту ошибку:
ОШИБКА - 2017-12-19 20:44:11 → Неустранимая ошибка - SOAP-ERROR: Parsing WSDL: Не удалось загрузить из http://soalurl.test:9087/orawsv?wsdl ': не удалось загрузить внешнюю сущность " http://soalurl.test:9087/orawsv?wsdl"
Я разрешил порт в брандмауэре и решил ошибку!
Ответ 6
503 означает, что функции работают, и вы получаете ответ от удаленного сервера, отрицающего вас. Если вы когда-либо пытались выполнить CURL-результаты Google, то происходит то же самое, потому что они могут обнаружить пользовательский агент, используемый файловыми_компонентами и cURL, и в результате блокируют эти пользовательские агенты. Также возможно, что сервер, к которому вы обращаетесь, также имеет IP-адрес, защищенный для таких методов.
В основном три общие причины, по которым команды не будут работать так же, как браузер в удаленной ситуации.
1) По умолчанию USER-AGENT заблокирован.
2) заблокирован IP-блок вашего сервера.
3) Удаленный хост имеет обнаружение прокси.
Ответ 7
Попробуйте включить расширение openssl в вашем php.ini, если оно отключено.
Таким образом, я мог получить доступ к веб-сервису без каких-либо дополнительных аргументов, т.е.
$client = new SoapClient(url);
Ответ 8
Я использую API AdWords, и иногда у меня такая же проблема.
Мое решение состоит в том, чтобы добавить
ini_set ('default_socket_timeout', 900);
по файлу
поставщик \googleads\googleads-php-lib\src\Google\AdsApi\AdsSoapClient.php строка 65
и в
поставщик \googleads-php-lib\src\Google\AdsApi\Adwords\Reporting\v201702\ReportDownloader.php строка 126
ini_set ('default_socket_timeout', 900);
$ requestOptions ['stream_context'] ['http'] ['timeout'] = "900";
Пакет Google перезаписывает параметр php.ini по умолчанию.
Иногда страница могла подключаться к https://adwords.google.com/api/adwords/mcm/v201702/ManagedCustomerService? wsdl, а иногда нет.
Если страница подключается один раз, кэш WSDL будет содержать одну и ту же страницу, и программа будет нормально, пока код не обновит кеш...
Ответ 9
Ничто из вышеперечисленного не работает для меня, поэтому после долгих исследований я закончил тем, что предварительно загрузил файл wsdl, сохранил его локально и передал этот файл в качестве первого параметра SoapClient.
Стоит упомянуть, что file_get_contents ($ serviceUrl) возвратил пустой ответ для меня, в то время как URL открылся в моем браузере. Вероятно, поэтому SoapClient также не смог загрузить документ wsdl. В итоге я скачал его с библиотекой php curl. Вот пример
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $serviceUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$wsdl = curl_exec($ch);
curl_close($ch);
$wsdlFile = '/tmp/service.wsdl';
file_put_contents($wsdlFile, $wsdl);
$client = new SoapClient($wsdlFile);
Конечно, вы можете реализовать собственную политику кэширования для файла wsdl, поэтому он не будет загружаться при каждом запросе.
Ответ 10
Добавление ?wsdl
в конце и вызов метода:
$client->__setLocation('url?wsdl');
помог мне.
Ответ 11
Вы не можете винить код все время, иногда может быть ваш URL неверен, дважды проверьте URL