我正在使用PHP从多个比特币交易所获取价格数据和交易量数据,但是当你加载页面时,它需要接近20秒。如何让加载时间更好?我认为它与卷曲有关。
<?php
function getData($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$rawData = curl_exec($curl);
curl_close($curl);
return json_decode($rawData, true);
}
//BTC Volume LocalBitcoins
$BTCVolumeLocal = getData('https://localbitcoins.com/bitcoinaverage/ticker-all-currencies/');
$LocalVolume = $BTCVolumeLocal["USD"]["volume_btc"];
//BTC Volume BTCE
$BTCVolumeBTCE = getData('https://btc-e.com/api/3/ticker/btc_usd');
$BTCEVolume = $BTCVolumeBTCE["btc_usd"]["vol_cur"];
//BTC Volume Bitstamp
$BTCVolumeStamp = getData('https://www.bitstamp.net/api/ticker/');
$StampVolume = $BTCVolumeStamp["volume"];
//BTC Volume Bitfinex
$BTCVolumeFinex = getData('https://api.bitfinex.com/v1/pubticker/btcusd');
$FinexVolume = $BTCVolumeFinex["volume"];
//BTC Volume OKCoin
$BTCVolumeOK = getData('https://www.okcoin.com/api/ticker.do?ok=1');
$OKCoinVolume = $BTCVolumeOK["ticker"]["vol"];
//BTC Volume LakeBTC
$BTCVolumeLake = getData('https://www.lakebtc.com/api_v1/ticker');
$LakeVolume = $BTCVolumeLake["USD"]["volume"];
//Totals the Volumes
$TotalVolume = $LakeVolume + $FinexVolume + $OKCoinVolume + $StampVolume + $BTCEVolume + $LocalVolume;
//Percents of Total Volume
$BTCEPercent = $BTCEVolume / $TotalVolume;
$StampPercent = $StampVolume / $TotalVolume;
$FinexPercent = $FinexVolume / $TotalVolume;
$OKPercent = $OKCoinVolume / $TotalVolume;
$LakePercent = $LakeVolume / $TotalVolume;
$LocalPercent = $LocalVolume / $TotalVolume;
//BTC Price BTCE
$BTCPriceBTCE = getData('https://btc-e.com/api/3/ticker/btc_usd');
$BTCEPrice = $BTCPriceBTCE["btc_usd"]["last"];
//BTC Price Bitstamp
$BTCPriceStamp = getData('https://www.bitstamp.net/api/ticker/');
$StampPrice = $BTCPriceStamp["last"];
//BTC Price Bitfinex
$BTCPriceFinex = getData('https://api.bitfinex.com/v1/pubticker/btcusd');
$FinexPrice = $BTCPriceFinex["last_price"];
//BTC Price OKCoin
$BTCPriceOK = getData('https://www.okcoin.com/api/ticker.do?ok=1');
$OKPrice = $BTCPriceOK["ticker"]["last"];
//BTC Price LakeBTC
$BTCPriceLake = getData('https://www.lakebtc.com/api_v1/ticker');
$LakePrice = $BTCPriceLake["USD"]["last"];
//BTC Price LocalBitcoins
$BTCPriceLocal = getData('https://localbitcoins.com/bitcoinaverage/ticker-all-currencies/');
$LocalPrice = $BTCPriceLocal["USD"]["avg_1h"];
//BTC Price * Percent
$BTCEPricePercent = $BTCEPrice * $BTCEPercent;
$StampPricePercent = $StampPrice * $StampPercent;
$FinexPricePercent = $FinexPrice * $FinexPercent;
$OKPricePercent = $OKPrice * $OKPercent;
$LakePricePercent = $LakePrice * $LakePercent;
$LocalPricePercent = $LocalPrice * $LocalPercent;
//Bitcoin Price
$bitcoinPrice = round($LakePricePercent + $OKPricePercent + $FinexPricePercent + $StampPricePercent + $BTCEPricePercent + $LocalPricePercent, 2);
?>
答案 0 :(得分:4)
如果API响应速度不够快且不受您的控制,您可能无法更改此内容。
并行查询它们可能会加快速度,但正如评论中所提到的,使用PHP通常并不容易。
如果只是页面的加载时间,您可以缓存API查询的结果:
答案 1 :(得分:2)
您有12个服务电话,20秒是真实的。我不熟悉您的应用,但您可以考虑实施一些缓存(将下载的数据保存到文件中,然后从下载的文件中加载)。
$url = 'http://www.example.com';
$content = '';
$file_name = 'tmp/cache.txt';
if(file_exists($file_name))){
$content = file_get_contents($file_name);
}else{
$content = file_get_contents($url);
//or $content = getData($url);
file_put_contents($file_name, $content);
}
function getData($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$rawData = curl_exec($curl);
curl_close($curl);
return json_decode($rawData, true);
}
答案 2 :(得分:1)
多线程和/或缓存,朋友。
PHP中的多线程并不比任何其他语言更难。您可以在此处找到相关说明:How can one use multi threading in PHP applications
你可以使用Memcache或Redis进行简单的缓存,并且有各种各样的教程和帮助在Web上使用它们来缓存PHP中的内容。
答案 3 :(得分:1)
我发现使用ajax结果都很快回来了,因为请求是异步运行的,到目前为止,这是在进行中......如果其他人可以看到我认为从这种方法中看到的好处毫无疑问,他们会指出它。
这个想法是一个js函数向php脚本发送一系列ajax请求,然后将curl请求发送给给定的各种比特币url。每个请求都设置为携带从请求返回的字段 - 然后php脚本向下钻取数据并找到该信息并返回到js。
计算各种百分比仍然是一个问题,因为您不必知道所有请求何时完成。我猜promises
可能有用吗?
当然使用ajax可以让页面快速加载 - 然后结果会随着&#39;直到完成.....
bitcoin.php
-----------
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
$cacert='c:\wwwroot\cacert.pem';
/* Two of the three params sent via ajax */
$url=$_POST['url'];
$fields=$_POST['fields'];
/* $fields might be a comma separated list of fields, or simply one - we want an array */
$params=( !empty( $fields ) && strstr( $fields, ',' ) ) ? explode( ',', $fields ) : (array)$fields;
$curl=curl_init( $url );
if( parse_url( $url, PHP_URL_SCHEME )=='https' ){
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $curl, CURLOPT_CAINFO, realpath( $cacert ) );
}
curl_setopt( $curl, CURLOPT_URL, $url );
curl_setopt( $curl, CURLOPT_HEADER, false );
curl_setopt( $curl, CURLOPT_FRESH_CONNECT, true );
curl_setopt( $curl, CURLOPT_FORBID_REUSE, true );
curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
curl_setopt( $curl, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_OLDEST );
curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 10 );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_USERAGENT, 'Bitcoin Fuzzer' );
$data=trim( curl_exec( $curl ) );
$status=curl_getinfo( $curl,CURLINFO_HTTP_CODE );
curl_close( $curl );
/* Deal with the response data */
if( $status==200 ){
$json=json_decode( $data );
/*
Hack:
there must be a better way to drill down dynamically through
an object structure but I was too tired to think straight
This simply echos back the response for javascript to deal with
but I guess one could make use of sessions to do the calculations
in php rather than js
*/
switch( count( $params ) ){
case 1:
$p1=$params[0];
print_r( $json->$p1 );
break;
case 2:
$p1=$params[0];
$p2=$params[1];
print_r( $json->$p1->$p2 );
break;
case 3:
$p1=$params[0];
$p2=$params[1];
$p3=$params[2];
print_r( $json->$p1->$p2->$p3 );
break;
}
}
}
?>
html页面 - 头:
<script type='text/javascript' charset='utf-8'>
/* simple ajax function */
function _ajax( url, options ){
var req=new XMLHttpRequest();
var callback=options.hasOwnProperty('callback') ? options.callback : false;
if( !callback ) return false;
var headers={
'Accept': "text/html, application/xml, application/json, text/javascript, "+"*"+"/"+"*"+"; charset=utf-8",
'Content-type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
};
var params=[];
if( options.hasOwnProperty('params') && typeof( options.params )=='object' ){
for( var n in options.params ) params.push( n + '=' + options.params[n] );
}
var args=options.hasOwnProperty('args') ? options.args : options;
req.onreadystatechange=function(){
if( req.readyState==4 ) {
if( req.status==200 ) options.callback.call( this, req.response, args );
else console.warn( 'Error: '+req.status+' status code returned' );
}
}
req.open( 'POST', url, true );
for( header in headers ) req.setRequestHeader( header, headers[ header ] );
req.send( params.join('&') );
}
var volumes=[];
var prices=[];
var tot_vols=0;
var tot_prices=0;
function bitcoin(){
var btc={
vols:{
'https:\/\/localbitcoins.com\/bitcoinaverage\/ticker-all-currencies\/':['USD','volume_btc'],
'https:\/\/btc-e.com\/api\/3\/ticker\/btc_usd':['btc_usd','vol_cur'],
'https:\/\/www.bitstamp.net\/api\/ticker\/':['volume'],
'https:\/\/api.bitfinex.com\/v1\/pubticker\/btcusd':['volume'],
'https:\/\/www.okcoin.com\/api\/ticker.do?ok=1':['ticker','vol'],
'https:\/\/www.lakebtc.com\/api_v1\/ticker':['USD','volume']
},
prices:{
'https:\/\/btc-e.com\/api\/3\/ticker\/btc_usd':['btc_usd','last'],
'https:\/\/www.bitstamp.net\/api\/ticker\/':['last'],
'https:\/\/api.bitfinex.com\/v1\/pubticker\/btcusd':['last_price'],
'https:\/\/www.okcoin.com\/api\/ticker.do?ok=1':['ticker','last'],
'https:\/\/www.lakebtc.com\/api_v1\/ticker':['USD','last'],
'https:\/\/localbitcoins.com\/bitcoinaverage\/ticker-all-currencies\/':['USD','avg_1h']
}
};
var url;
var vols=btc.vols;
var prices=btc.prices;
for( url in vols ){
getbitcoin.call( this, url, vols[url], 'volumes' );
}
for( url in prices ){
getbitcoin.call( this, url, vols[url], 'prices' );
}
}
function getbitcoin( url, fields, type ){
var options={
callback:cbbtc,
method:'POST',
params:{
'fields':fields,
'type':type,
'url':url
}
};
_ajax.call( this, '/test/bitcoin.php', options );
}
function cbbtc(r,o){
switch( o.params.type ){
case 'volumes':
tot_vols += parseFloat( r );
volumes.push( parseFloat( r ) );
document.getElementById('btc_vols').value=tot_vols;
break;
case 'prices':
tot_prices += parseFloat( r );
prices.push( parseFloat( r ) );
document.getElementById('btc_prices').value=tot_prices;
break;
}
}
/* launch the function when the page is ready */
document.addEventListener( 'DOMContentLoaded', bitcoin, false );
</script>
html page - body:
/* These simply receive values for testing */
<input type='text' id='btc_vols' />
<input type='text' id='btc_prices' />