php - 通过 https : SSL3_GET_SERVER_CERTIFICATE 使用 php 加载外部 xml 文件时出错

标签 php xml

我无法加载 xml 文件。

这段代码效果很好:

$url = 'http://www.w3schools.com/xml/note.xml';
$xml = simplexml_load_file($url);
print_r($xml);

但是这个

$url = 'https://www.boardgamegeek.com/xmlapi2/thing?id=105551';
$xml = simplexml_load_file($url);
print_r($xml);

没用。我收到此错误:

Warning: simplexml_load_file(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file(): Failed to enable crypto in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file(https://www.boardgamegeek.com/xmlapi2/thing?id=105551): failed to open stream: operation failed in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file(): I/O warning : failed to load external entity "https://www.boardgamegeek.com/xmlapi2/thing?id=105551" in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19

来自 boardgamegeek 的 xml 文件适用于其他站点。我应该使用不同的 php 代码来加载该 xml 文件吗?

最佳答案

简短的食谱答案:

  1. 下载https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt并将该文件放在您的服务器上。
  2. 添加

    $context = stream_context_create(array('ssl'=>array(
        'verify_peer' => true,
        'cafile' => '/path/to/ca-bundle.crt'
    )));
    libxml_set_streams_context($context);

添加到您的脚本,以便它在 simplexml_load_file() 之前执行。
或者 - 而不是上面的代码 - 在您的 php.ini 中设置 openssl.cafile=/path/to/ca-bundle.crt

非常简短的解释:
您的 php 版本使用 openssl 来处理 https 传输。 openssl 尝试验证服务器是否真的是它声称的那个人。它通过检查其证书是否可信来做到这一点。 X.509 证书包含一些关于所有者的数据并由颁发者签名(它本身有一个再次签名的证书等等,直到所有者和颁发者相同的证书 -> 自签名/根证书)。如果在该证书链中有(至少)一个证书,openssl“说”:“好的,我已被指示信任这个证书”,则该证书被认为是“受信任的”。该指令采用(或可以采用)“这是一个包含您应该信任的证书的文件”(cafile) 的形式。
上面的代码告诉 php 的 libxml-wrapper 告诉 openssl 当 simplexml_load_file 使用 https/openssl-wrapper 时那个 cafile 在哪里。
openssl.cafile=/path/to/ca-bundle.crt 只是将其设置为默认值;除非另有说明,否则所有 openssl 操作都将使用该文件 - 包括 libxml/simple_xml_loadfile。

我链接到的 ca-bundle.crt 来自一个项目,该项目“声称”提供与 mozilla firefox 一起提供的提取的根证书。关于“声明”:我没有理由怀疑这确实是未篡改的根证书列表;但您永远不会知道:您信任 a) 这个项目和 b) mozilla 做得很好并且只将可信赖的证书放在该列表中....

有关更多说明,请参阅 http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-%28HTTPS-SSL-and-TLS%29.html#php-streams

关于php - 通过 https : SSL3_GET_SERVER_CERTIFICATE 使用 php 加载外部 xml 文件时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32621929/

相关文章:

Php fetch 返回字符串而不是 bool 值 "true/false"

php - 使用 IIS 在 Windows Server 上上传 PHP 视频时出现 413 错误

php - PHP <5.3 中的真正闭包

iphone - 如何使用 GDataXML 解析器解析嵌套的 xml?

objective-c - iOS 清理错误的 XML

php - HttpKernel\Exception\MethodNotAllowedHttpException : The GET method is not supported for this route. Supported methods: POST in Laravel

javascript - PHP 或 Javascript - 查找特定字符串

xml - 如何使 maven-jaxb2-plugin 忽略生成类(如果它已存在于我的项目源中)

android - 解析android资源@android :color/transparent#00000000

java - JAXB 将 XML 子对象解析为 null,仅在对象中设置了属性