I can't get a xml file to load.
This code works great:
$url = 'http://www.w3schools.com/xml/note.xml';
$xml = simplexml_load_file($url);
print_r($xml);
But this one
$url = 'https://www.boardgamegeek.com/xmlapi2/thing?id=105551';
$xml = simplexml_load_file($url);
print_r($xml);
doesn't work. I get this error:
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
The xml file from boardgamegeek works on other sites. Should I use a different php code to load that xml file?
short cookbook answer:
Add
$context = stream_context_create(array('ssl'=>array( 'verify_peer' => true, 'cafile' => '/path/to/ca-bundle.crt' ))); libxml_set_streams_context($context);
to your script so it gets executed before simplexml_load_file().
Or - instead of the code above - set openssl.cafile=/path/to/ca-bundle.crt
in your php.ini.
Very short explaination:
Your php version uses openssl to handle the https transport. openssl tries to verify whether the server really is who it claims to be. It does that by checking whether its certificate is trusted. A X.509 certificate contains some data about the owner and is signed by an issuer (itself having a certificate that is again signed and so on and on until a certificate where owner and issuer are identical -> self-signed/root certificate). A certificate is considered "trusted" if in that chain of certificates there is (at least) one certificate on which openssl "says": "ok, I have been instructed to trust this one". This instruction takes the form of (or can take the form of) "here's a file containing certificates that you're supposed to trust" (cafile).
The above code tells the libxml-wrapper of php to tell openssl where that cafile is when simplexml_load_file uses the https/openssl-wrapper.
And openssl.cafile=/path/to/ca-bundle.crt
just sets it as default; unless instructed otherwise all openssl operations will use that file - including libxml/simple_xml_loadfile.
The ca-bundle.crt I've linked to is from a project that "claims" to provide the extracted root certificates as shipped with mozilla firefox. Regarding "claims": I have no reason to doubt that this really is the untampered root cert list; but you never know: You're putting your trust a) in this project and b) mozilla doing a good job and only putting trustworthy certificates in that list....
for more explaination see http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-%28HTTPS-SSL-and-TLS%29.html#php-streams
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With