php SOAP-ERROR:解析 WSDL:无法加载 - 但适用于 WAMP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21861077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:29:03  来源:igfitidea点击:

SOAP-ERROR: Parsing WSDL: Couldn't load from - but works on WAMP

phpsoap

提问by clarkk

This works fine on my WAMP server, but doesn't work on the linux master server!?

这在我的 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();
}

What am I missing here?! :(

我在这里错过了什么?!:(

SOAP is enabled

启用了 SOAP

Error

错误

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"

Call the URL from PHP

从 PHP 调用 URL

Calling the URL from PHP returns error

从 PHP 调用 URL 返回错误

$wsdl = file_get_contents('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl');
echo $wsdl;

Error

错误

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

Call the URL from command line

从命令行调用 URL

Calling the URL from the linux command line HTTP 200is returned with a XML response

从 linux 命令行调用 URLHTTP 200会返回一个 XML 响应

curl http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

回答by Ivar

For some versions of php, the SoapClient does not send http user agent information. What php versions do you have on the server vs your local WAMP?

对于某些版本的 php,SoapClient 不会发送 http 用户代理信息。与本地 WAMP 相比,您在服务器上有哪些 php 版本?

Try to set the user agent explicitly, using a context stream as follows:

尝试使用上下文流显式设置用户代理,如下所示:

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();
}

Edit

编辑

It actually seems to be some issues with the web service you are using. The combination of HTTP over IPv6, and missing HTTP User Agent string, seems to give the web service problems.

实际上,您使用的 Web 服务似乎存在一些问题。IPv6 上的 HTTP 和缺少 HTTP 用户代理字符串的组合似乎给 Web 服务带来了问题。

To verify this, try the following on your linux host:

要验证这一点,请在您的 linux 主机上尝试以下操作:

curl  -A ''  -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

this IPv6 request fails.

此 IPv6 请求失败。

curl  -A 'cURL User Agent'  -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

this IPv6 request succeeds.

此 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

both these IPv4 request succeeds.

这两个 IPv4 请求都成功。

Interesting case :) I guess your linux host resolves ec.europa.eu to its IPv6 address, and that your version of SoapClient did not add a user agent string by default.

有趣的案例 :) 我猜您的 linux 主机将 ec.europa.eu 解析为其 IPv6 地址,并且您的 SoapClient 版本默认没有添加用户代理字符串。

回答by gogagubi

Try this. I hope it helps

尝试这个。我希望它有帮助

$options = [
    'cache_wsdl'     => WSDL_CACHE_NONE,
    'trace'          => 1,
    'stream_context' => stream_context_create(
        [
            'ssl' => [
                'verify_peer'       => false,
                'verify_peer_name'  => false,
                'allow_self_signed' => true
            ]
        ]
    )
];

$client = new SoapClient($url, $options);

回答by Attila Szeremi

This issue can be caused by the libxml entity loader having been disabled.

此问题可能是由于 libxml 实体加载器已被禁用所致。

Try running libxml_disable_entity_loader(false);before instantiating SoapClient.

libxml_disable_entity_loader(false);在实例化之前尝试运行SoapClient

回答by klugerama

Try changing

尝试改变

$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]);

to

$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY]);

Also (whether that works or not), check to make sure that /tmpis writeable by your web server and that it isn't full.

另外(无论是否有效),请检查以确保/tmp您的 Web 服务器可写入并且未满。

回答by EmRa228

It may be helpful for someone, although there is no precise answer to this question.

尽管这个问题没有准确的答案,但它可能对某人有所帮助。

My soap url has a non-standard port(9087 for example), and firewall blocked that request and I took each time this error:

我的soap url有一个非标准端口(例如9087),防火墙阻止了该请求,每次出现此错误时我都会接受:

ERROR - 2017-12-19 20:44:11 --> Fatal Error - SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://soalurl.test:9087/orawsv?wsdl' : failed to load external entity "http://soalurl.test:9087/orawsv?wsdl"

错误 - 2017-12-19 20:44:11 --> 致命错误 - SOAP 错误:解析 WSDL:无法从“ http://soalurl.test:9087/orawsv?wsdl”加载:无法加载外部实体“ http://soalurl.test:9087/orawsv?wsdl

I allowed port in firewall and solved the error!

我在防火墙中允许端口并解决了错误!

回答by Madan

503 means the functions are working and you're getting a response from the remote server denying you. If you ever tried to cURL google results the same thing happens, because they can detect the user-agent used by file_get_contents and cURL and as a result block those user agents. It's also possible that the server you're accessing from also has it's IP address blackballed for such practices.

503 表示功能正在运行,并且您从远程服务器收到拒绝您的响应。如果您曾经尝试 cURL google 结果,也会发生同样的事情,因为它们可以检测 file_get_contents 和 cURL 使用的用户代理,并因此阻止这些用户代理。您正在访问的服务器也有可能因为这种做法而将其 IP 地址列入黑名单。

Mainly three common reasons why the commands wouldn't work just like the browser in a remote situation.

主要是命令在远程情况下无法像浏览器一样工作的三个常见原因。

1) The default USER-AGENT has been blocked. 2) Your server's IP block has been blocked. 3) Remote host has a proxy detection.

1) 默认的 USER-AGENT 已被阻止。2) 您服务器的 IP 块已被阻止。3)远程主机有代理检测。

回答by Juan Fernando

Try enabling openssl extension in your php.ini if it is disabled. This way I could access the web service without need of any extra arguments, i.e.,

如果它被禁用,请尝试在 php.ini 中启用 openssl 扩展。这样我就可以访问网络服务而无需任何额外的参数,即,

$client = new SoapClient(url);

回答by Shumoapp

None of the above works for me, so after a lot of research, I ended up pre-downloading the wsdl file, saving it locally, and passing that file as the first parameter to SoapClient.

以上都不适合我,所以经过大量研究,我最终预先下载了 wsdl 文件,将其保存在本地,并将该文件作为第一个参数传递给 SoapClient。

Worth mentioning is that file_get_contents($serviceUrl) returned empty response for me, while the url opened fine in my browser. That is probably why SoapClient also could not load the wsdl document. So I ended up downloading it with the php curl library. Here is an example

值得一提的是 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);

You can of course implement your own caching policy for the wsdl file, so it won't be downloaded on each request.

您当然可以为 wsdl 文件实现自己的缓存策略,因此不会在每次请求时都下载它。

回答by Sakezzz

Adding ?wsdlat the end and calling the method:

?wsdl在最后添加并调用方法:

$client->__setLocation('url?wsdl'); 

helped to me.

对我有帮助。

回答by Yohann Nizon

I use the AdWords API, and sometimes I have the same problem. My solution is to add ini_set('default_socket_timeout', 900); on the file vendor\googleads\googleads-php-lib\src\Google\AdsApi\AdsSoapClient.php line 65

我使用 AdWords API,有时也会遇到同样的问题。我的解决方案是添加 ini_set('default_socket_timeout', 900); 在文件 vendor\googleads\googleads-php-lib\src\Google\AdsApi\AdsSoapClient.php 第 65 行

and in the vendor\googleads-php-lib\src\Google\AdsApi\Adwords\Reporting\v201702\ReportDownloader.php line 126 ini_set('default_socket_timeout', 900); $requestOptions['stream_context']['http']['timeout'] = "900";

并在 vendor\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 package overwrite the default php.ini parameter.

Google 包会覆盖默认的 php.ini 参数。

Sometimes, the page could connect to 'https://adwords.google.com/api/adwords/mcm/v201702/ManagedCustomerService?wsdl and sometimes no. If the page connects once, The WSDL cache will contain the same page, and the program will be ok until the code refreshes the cache...

有时,页面可能会连接到“ https://adwords.google.com/api/adwords/mcm/v201702/ManagedCustomerService?wsdl”,有时则不会。如果页面连接一次,WSDL缓存将包含相同的页面,程序将正常,直到代码刷新缓存...