我正在建立一个个人股票平台(非分布式)。我想要的一个组件是此页面上的 EPS 图表:
正如你所看到的,该页面是
https
,所以经过几天的敲定,我启用了 openssl
,现在它似乎适用于所有 https
页面,例如 facebook 和 twitter 的主页,但它是仍然无法满足我需要的需求。
file_get_contents('https://facebook.com'); /* works */
file_get_contents('https://twittercom'); /* works */
file_get_contents('https://eresearch.fidelity.com/eresearch/evaluate/fundamentals/earnings.jhtml?stockspage=earnings&symbols=AAPL&showPriceLine=yes');
我收到警告:
Warning: file_get_contents(): SSL: crypto enabling timeout in C:\xampp\htdocs\index.php on line 3
Warning: file_get_contents(): Failed to enable crypto in C:\xampp\htdocs\index.php on line 3
Warning: file_get_contents(https://eresearch.fidelity.com/eresearch/evaluate/fundamentals/earnings.jhtml?stockspage=earnings&symbols=AAPL&showPriceLine=yes): failed to open stream: operation failed in C:\xampp\htdocs\index.php on line 3
Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\index.php on line 3
我能看到的唯一区别是保真度页面在 https 标签附近有一个三角形。
好的,我找到了解决方案。问题是该站点使用 SSLv3。而且我知道openssl模块存在一些问题。前段时间我的 SSL 版本也遇到了同样的问题。
<?php
function getSSLPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLVERSION,3);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
var_dump(getSSLPage("https://eresearch.fidelity.com/eresearch/evaluate/analystsOpinionsReport.jhtml?symbols=api"));
?>
当您使用curl 将SSL 版本设置为v3 时,它就可以工作。
编辑:
Windows 下的另一个问题是您无权访问证书。所以直接把根证书放到curl中。
http://curl.haxx.se/docs/caextract.html
您可以在这里下载根证书。
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/certs/cacert.pem");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
然后您可以将
CURLOPT_SSL_VERIFYPEER
选项与 true
一起使用,否则会出现错误。
有同样的问题 - 它位于 ca 证书中的某个位置,所以我使用了用于 curl 的 ca 捆绑包,并且它有效。您可以在此处下载curl ca捆绑包:https://curl.haxx.se/docs/caextract.html
有关加密和安全问题,请参阅这篇有用的文章:
https://www.venditan.com/labs/2014/06/26/ssl-and-php-streams-part-1-you-are-doing-it-wrongtm/432
这是例子:
$url = 'https://www.example.com/api/list';
$cn_match = 'www.example.com';
$data = array (
'apikey' => '[example api key here]',
'limit' => intval($limit),
'offset' => intval($offset)
);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
, 'ssl' => array(
'verify_peer' => true,
'cafile' => [path to file] . "cacert.pem",
'ciphers' => 'HIGH:TLSv1.2:TLSv1.1:TLSv1.0:!SSLv3:!SSLv2',
'CN_match' => $cn_match,
'disable_compression' => true,
)
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
希望有帮助
对我有用的解决方法是禁用对等验证。使用它时要小心,因为它不应该在生产中使用。
$arrContextOptions = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
)
);
$context = stream_context_create($arrContextOptions);
$contents = file_get_contents($url,false,$context);
检查 php-fpm 服务当前使用哪个 php.ini 文件。设置curl_cainfo和openssl.cafile变量使用相同且有效的ca文件。这将解决我的问题。
就我而言,我收到以下消息:
PHP 消息:PHP 警告:fopen():SSL 操作失败,代码为 1。OpenSSL 错误消息:
错误:1416F086:SSL 例程:tls_process_server_certificate:证书验证失败...在线...
PHP 消息:PHP 警告:fopen(): 无法在线启用加密...
PHP 消息:PHP 警告:fopen(...):无法打开流:操作失败...在线...”,同时从上游读取响应头,客户端:...,服务器:,请求:“GET ... HTTP/1.0”,上游:“fastcgi://unix:/run/php/php7.0-fpm.sock:”,主机:“...”
要修复它,我需要安装
ca-certificates
(我在 LXC 容器中运行)。