在这两种情况下,相应的WSDL载荷都在Firefox中加载并显示"安全连接"。PHP版本为5.6.22,这意味着默认情况下,PHP将验证连接是否安全(与PHP 5.5.50和先前的http://php.net/manual/manual/en/en/migration 56.openssl.openssl.php相反)。这个想法是要精确执行安全的连接,两种情况都是为了确保安全,正在隐式验证。
需要这种情况才能工作(情况A):
$wsdl = 'https://palena.sii.cl/DTEWS/CrSeed.jws?WSDL';
$entity_loader_status_old = libxml_disable_entity_loader(false);
$SoapClient = new SoapClient($wsdl);
$seed = $SoapClient -> getSeed();
libxml_disable_entity_loader($entity_loader_status_old);
var_dump($seed);
错误:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://palena.sii.cl/DTEWS/CrSeed.jws?WSDL' : failed to load external entity "https://palena.sii.cl/DTEWS/CrSeed.jws?WSDL"
in /path/to/script.php:3
Stack trace:
#0 /path/to/script.php(3): SoapClient->SoapClient('https://palena....')
#1 {main}
thrown in /path/to/script.php on line 3
此示例案例工作(情况B):
$wsdl = 'https://www.lb.lt/webservices/ExchangeRates/ExchangeRates.asmx?WSDL';
$entity_loader_status_old = libxml_disable_entity_loader(false);
$SoapClient = new SoapClient($wsdl);
$exchangeRate = $SoapClient -> getExchangeRate();
libxml_disable_entity_loader($entity_loader_status_old);
var_dump($exchangeRate);
转储:
object(stdClass)#2 (1) { ["getExchangeRateResult"]=> string(2) "-1" }
注意:这种情况是辅助的,仅用于演示。
案例A 工作了几个月(始终是PHP 5.6.x),仅两天前,它就停止工作并丢弃了错误,但没有更改代码。失败日期接近 vem-from 网络服务证书的日期(2016年12月12日至2017年12月14日),看起来服务器刚刚续签了证书(在详细信息中看到了日期通过将WSDL地址加载到浏览器中),这很可能与问题有关。
显然,要受到客户的信任,更新的证书需要一个特定的中间证书,该证书散布不足,因此必须找到中间证书并将其添加到受信任的中间证书的捆绑包中。为此,找到了中间证书,通过使用其下载地址,在客户端中执行了下三行:
wget http://symantec.tbs-certificats.com/Symantec_Class_3_EV_SSL_CA_G3.crt
cp Symantec_Class_3_EV_SSL_CA_G3.crt
/etc/pki/ca-trust/source/anchors update-ca-trust
在某种程度上似乎有效,因为现在错误不是从第3行(SoapClient
)产生的,而是从第4行(getSeed
)中:
Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host
in /path/to/script.php:4
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'https://palena....', '', 1, 0)
#1 /path/to/script.php(4): SoapClient->__call('getSeed', Array)
#2 /path/to/script.php(4): SoapClient->getSeed()
#3 {main}
thrown in /path/to/script.php on line 4
案例A 在禁用安全连接验证时工作(但这不是解决方案,因为它会破坏安全性):
$wsdl = 'https://palena.sii.cl/DTEWS/CrSeed.jws?WSDL';
$entity_loader_status_old = libxml_disable_entity_loader(false);
$SoapClient = new SoapClient(
$wsdl
, [
'stream_context' => stream_context_create([
'ssl' => [
'verify_peer' => false,
],
]),
]
);
$seed = $SoapClient -> getSeed();
libxml_disable_entity_loader($entity_loader_status_old);
var_dump($seed);
转储:
string(219) "00436612495400"
为什么案例A不适用于安全验证以及如何修复它?
对我来说,案例b也有效:
它重新调整以下:
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_BODY>
<SEMILLA>004361002032</SEMILLA></SII:RESP_BODY>
<SII:RESP_HDR><ESTADO>00</ESTADO></SII:RESP_HDR>
</SII:RESPUESTA>
i M使用PHP版本5.5.9