Php SOAP-ERROR:解析WSDL:can';t从加载-但在WAMP上工作

Php SOAP-ERROR:解析WSDL:can';t从加载-但在WAMP上工作,php,soap,Php,Soap,这在我的WAMP服务器上运行良好,但在linux主服务器上不起作用 try{ $client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]); $result = $client->checkVat([ 'countryCode' => 'DK', 'vatNumber' =&

这在我的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已启用

错误 从PHP调用URL 从PHP调用URL返回错误

$wsdl = file_get_contents('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl');
echo $wsdl;
错误 从命令行调用URL 从linux命令行
HTTP200
调用URL将返回一个XML响应

curl http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
试着改变

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


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

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

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

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();
}
编辑 实际上,您正在使用的web服务似乎存在一些问题。IPv6上的HTTP和缺少HTTP用户代理字符串的组合似乎给web服务带来了问题

要验证这一点,请在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请求都成功

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

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

503表示功能正在工作,并且您从远程服务器收到拒绝您的响应。如果你曾经尝试卷曲谷歌结果,同样的事情也会发生,因为它们可以检测文件内容和卷曲使用的用户代理,从而阻止这些用户代理。也有可能您访问的服务器的IP地址也被禁止使用

主要有三个常见的原因,说明这些命令在远程情况下不能像浏览器那样工作

1) 默认用户代理已被阻止。 2) 服务器的IP块已被阻止。
3) 远程主机具有代理检测

此问题可能是由于禁用了libxml实体加载程序造成的


尝试运行
libxml\u禁用\u实体\u加载程序(false)
在实例化
SoapClient

之前,我使用AdWords API,有时我也会遇到同样的问题。 我的解决办法是添加 ini设置(“默认套接字超时”,900); 存档 vendor\googleads\googleads php lib\src\Google\AdsApi\AdsSoapClient.php第65行

在 vendor\googleads php lib\src\Google\AdsApi\Adwords\Reporting\v201702\ReportDownloader.php第126行 ini设置(“默认套接字超时”,900); $requestOptions['stream_context']['http']['timeout']=“900”

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

有时,页面可以连接到' i/adwords/mcm/v201702/ManagedCustomerService?wsdl,有时是no。
如果页面连接一次,WSDL缓存将包含相同的页面,程序将正常运行,直到代码刷新缓存…

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

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

错误-2017-12-19 20:44:11-->致命错误-SOAP错误:解析 WSDL:无法从“”加载: 无法加载外部实体“”


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

试试这个。我希望有帮助

$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);

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

$client = new SoapClient(url);

以上这些都不适用于我,所以经过大量研究,我最终预下载了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文件实现自己的缓存策略,因此不会在每次请求时下载它

在末尾添加
?wsdl
,并调用该方法:

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

帮助了我。

你不能一直怪代码,有时可能是你的url错误,请仔细检查url

我可能已经读了两天关于这方面的所有问题了。没有一个答案对我有用

在我的例子中,我缺少PHP的cURL模块。

请注意,仅仅因为您可以在终端上使用cURL,并不意味着您拥有PHP cURL模块并且它是活动的。 显示它时没有错误。甚至不在
/var/log/apache2/error.log上

如何安装模块: (更换原版本的版本号)


经过数小时的分析阅读了大量的日志和互联网,最终发现了问题

如果您使用docker和PHP7.4(我的案例),您可能会遇到错误,因为OpenSSL中的默认安全级别对于wsdl证书来说太高。即使您禁用了验证并允许自签名SoapClient选项。

您需要在
/etc/ssl/openssl.cnf
中使用较低的seclevelDEFAULT@SECLEVEL=2

DEFAULT@SECLEVEL=1
或者直接添加到Dockerfile中

RUN sed -i "s|DEFAULT@SECLEVEL=2|DEFAULT@SECLEVEL=1|g" /etc/ssl/openssl.cnf
资料来源:


您可以通过在容器上运行来验证它

curl-A'curl用户代理'-4https://ewus.nfz.gov.pl/ws-broker-server-ewus/services/Auth?wsdl
在更改之前,我遇到了一个错误:

SSL routines:tls_process_ske_dhe:dh key too small
我也有同样的问题

在本地机器上,一切正常(wamp+php5.5.38或vagrant+PHP7.4),但在ProdLinux服务器上,我遇到了错误

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"
从chrome中的重定向路径插件中,我发现永久重定向到https,但将url更改为https并没有帮助

Status Code    URL    IP    Page Type    Redirect Type    Redirect URL    
301 147.67.210.30服务器\u永久重定向 200 147.67.210.30正常无

经过几次尝试,不同的代码解决方案帮助我的服务器提供商。他在IP forw中发现了这个问题
SSL routines:tls_process_ske_dhe:dh key too small
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"
Status Code    URL    IP    Page Type    Redirect Type    Redirect URL    
http://ec.europa.eu/

Pinging ec.europa.eu [147.67.34.30] with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
// https://www.php.net/manual/en/context.socket.php

$streamContextOptions = [
  'socket' => [
    'bindto' => '0:0'
  ],
];

$streamContext = stream_context_create($streamContextOptions);

$soapOptions = [
  'stream_context' => $streamContext
];

$service = new SoapClient('https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', $soapOptions);