从JSON获取数据并更新CSV文件的PHP脚本,cpu使用率高
我制作了这个PHP脚本,它从JSON文件获取数据,然后编辑或在多个CSV文件的底部添加一行。 使用cronjob,该脚本每60秒运行一次,运行时会占用大量CPU。我不是专家,我可能需要一些技巧来优化它,甚至改变它的工作方式以获得更好的性能。 谢谢你的帮助从JSON获取数据并更新CSV文件的PHP脚本,cpu使用率高,php,json,csv,fputcsv,Php,Json,Csv,Fputcsv,我制作了这个PHP脚本,它从JSON文件获取数据,然后编辑或在多个CSV文件的底部添加一行。 使用cronjob,该脚本每60秒运行一次,运行时会占用大量CPU。我不是专家,我可能需要一些技巧来优化它,甚至改变它的工作方式以获得更好的性能。 谢谢你的帮助 //get data from json $coins = 'BTC,ETH,BNB,XRP,USDT,DOT'; $url = 'https://apilink'.$coins; $ch = curl_init($url); curl_set
//get data from json
$coins = 'BTC,ETH,BNB,XRP,USDT,DOT';
$url = 'https://apilink'.$coins;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$stats = json_decode($result, true);
curl_close($ch);
$timeupd = date('d/m/Y H:i:s');
//FIRST COIN
$date = $stats[0]['price_date'];
$createDate = new DateTime($date);
$date = $createDate->format('Y-m-d');
$cap = $stats[0]['market_cap'];
$high = $stats[0]['high'];
$daypc = number_format((float)$stats[0]['1d']['price_change_pct'] * 100, 2, '.', '');
$weekpc = number_format((float)$stats[0]['7d']['price_change_pct'] * 100, 2, '.', '');
$adjclose = $stats[0]['price'];
$volume = $stats[0]['1d']['volume'];
$monthpc = number_format((float)$stats[0]['30d']['price_change_pct'] * 100, 2, '.', '');
$yearpc = number_format((float)$stats[0]['365d']['price_change_pct'] * 100, 2, '.', '');
$ytdpc = number_format((float)$stats[0]['ytd']['price_change_pct'] * 100, 2, '.', '');
//create array
$array = array($date, $cap, $high, $daypc, $weekpc, $adjclose, $volume, $monthpc, $yearpc, $ytdpc, $timeupd);
//get last row from csv file
$rows = file('/firstcoin.csv');
$last_row = array_pop($rows);
$data = str_getcsv($last_row);
//add new line or modify it
if($date == $data[0] && !empty($stats[0]['price'])){
$f = '/firstcoin.csv';
$rows = file($f);
array_pop($rows); // remove final element/row from $array
file_put_contents($f, implode($rows)); // convert back to string and overwrite file
$handle = fopen("/firstcoin.csv", "a");
fputcsv($handle, $array);
fclose($handle);
} elseif($date != $data[0] && !empty($stats[0]['price'])) {
$handle = fopen("/firstcoin.csv", "a");
fputcsv($handle, $array);
fclose($handle);
} else {
echo 'EMPTY JSON RESPONSE FOR FIRST COIN';
}
//SECOND COIN
//....other csv
//THIRD COIN
//....other csv
//ETC
您至少要将整个文件读入内存一次,然后在第一种情况下将整个文件写回磁盘。这非常昂贵,而且随着文件的增长,情况会变得更糟。因为您只需要读写文件的末尾,所以应该找到一种方法,只读取最后一行,可以选择删除它,然后将新行写入文件的末尾 这是一个概念证明,您需要仔细测试这种技术,以确保它与系统上的行结束符一起工作
<?php
//get last row from csv file
$handle = fopen('/firstcoin.csv', 'a+');
$data = getLastCsvLine($handle, $lastLineOffset);
//add new line or modify it
if($date == $data[0] && !empty($stats[0]['price'])){
/*
* Remove last line from the file
* getLastCsvLine will set the file pointer to the beginning of the line,
* so we can just truncate from there then add our line
*/
ftruncate($handle, $lastLineOffset);
fputcsv($handle, $array);
} elseif($date != $data[0] && !empty($stats[0]['price'])) {
fputcsv($handle, $array);
} else {
echo 'EMPTY JSON RESPONSE FOR FIRST COIN';
}
fclose($handle);
/**
* Get the last CSV line in a file
*
* @param $fileHandle
* @return array|false
*/
function getLastCsvLine($fileHandle, &$lastLineOffset)
{
// Set the initial reverse offset
$cursor = -1;
// Set the file pointer to the end of the file
fseek($fileHandle, $cursor, SEEK_END);
// Rewind past any newlines at the end of the file
do
{
$char = fgetc($fileHandle);
fseek($fileHandle, --$cursor, SEEK_END);
} while( $char === "\n" || $char === "\r" );
// Read backwards until we hit the next newline or the beginning of the file
do
{
// Step backwards one byte
fseek($fileHandle, --$cursor, SEEK_END);
// Get the current char
$char = fgetc($fileHandle);
// Test to see if it is a newline char
$foundLineStart = ( $char === false || $char === "\n" || $char === "\r" );
} while (!$foundLineStart);
// Set the last line offset var and seek to the offset
$lastLineOffset = ftell($fileHandle);
// Return the data for the line
return fgetcsv($fileHandle);
}
您好,感谢您花时间编写此解决方案。我对此唯一的问题是,无论什么情况,它都会向csv文件添加一个新行(即使第一个if语句为true并且“ftruncate”应该启动并执行其工作),显然getLastCsvLine函数在最后一行的末尾设置指针,因为该文件以一个新的空行结尾(执行“echo ftell()”返回50908,文件长度为50909)尝试更新的示例,它应该可以解决该问题。效果很好,谢谢!