我通过记录每分钟在线的人来监控服务器上的玩家活动。播放器列表存储为varchar字段中的单个逗号分隔字符串。
我让玩家选择一个日期来显示当天和那个月的在线人员。
该脚本运行良好并按预期执行,但是我需要花费很长时间来处理数据。目前加载页面大约需要10秒钟。
我的问题是:是否有更有效,更快捷的获取和显示数据的方式?
显示玩家活动的 if(isset($_POST['submit'])){
$chosenDay =$_POST['day'];
$chosenMonth =$_POST['month'];
$chosenYear =$_POST['year'];
?>
<article id="intro">
<div id="motd">
<h2>Player Activity Graph</h2>
<form class="form" action="activity.php" method="POST">
<select name="year" class="date-select">
<?php
echo '<option value="'.$chosenYear.'" selected>'.$chosenYear.'</option>';
for($i = 2013; $i<$currentYear; $i++){
echo '<option value="'.$i.'">'.$i.'</option>';
}
?>
</select>
<select name="month" class="date-select">
<?php
echo '<option value="'.$chosenMonth.'" selected>'.$chosenMonth.'</option>';
for($i = 1; $i<12; $i++){
echo '<option value="'.$i.'">'.$i.'</option>';
}
?>
</select>
<select name="day" class="date-select">
<?php
echo '<option value="'.$chosenDay.'" selected>'.$chosenDay.'</option>';
for($i = 1; $i<=$days_in_month; $i++){
echo '<option value="'.$i.'">'.$i.'</option>';
}
?>
</select>
<input type="submit" name="submit" id="activitysubmit" value="submit" />
</form>
</div>
<p>Please select a date and press submit. You will be presented with a<br /> graph of player activity. Hover over a bar to view the players online at<br /> that time.</p><br /><br />
<?php
$chosenDate =$chosenYear.'-'.$chosenMonth.'-'.$chosenDay;
$get = $dbh->prepare("SELECT * FROM dcpmc_players_online WHERE date=?");
$get->bindParam(1, $chosenDate, PDO::PARAM_STR);
$get->execute();
$result = $get->fetchAll();
if(count($result) > 0 ){
$left = 0;
echo '<div class="chartWrapper">';
echo '<p>Players online today</p>';
echo '<div class="sidelegend"><p>Player count</p></div>';
echo '<div class="bottomlegend">
<div class="time"><p>0</p></div>
<div class="time"><p>1</p></div>
<div class="time"><p>2</p></div>
<div class="time"><p>3</p></div>
<div class="time"><p>4</p></div>
<div class="time"><p>5</p></div>
<div class="time"><p>6</p></div>
<div class="time"><p>7</p></div>
<div class="time"><p>8</p></div>
<div class="time"><p>9</p></div>
<div class="time"><p>10</p></div>
<div class="time"><p>11</p></div>
<div class="time"><p>12</p></div>
<div class="time"><p>13</p></div>
<div class="time"><p>14</p></div>
<div class="time"><p>15</p></div>
<div class="time"><p>16</p></div>
<div class="time"><p>17</p></div>
<div class="time"><p>18</p></div>
<div class="time"><p>19</p></div>
<div class="time"><p>20</p></div>
<div class="time"><p>21</p></div>
<div class="time"><p>22</p></div>
<div class="time"><p>23</p></div>
<div class="time"><p>24</p></div>
</div>';
echo '<div class="bottomlegend2"><p>Time in GMT</p></div>';
// loop through every hour of today
for($h = 0; $h<=$hours; $h++){
// add a zero in front of the first 9 hours
if($h < 10){$h='0'.$h;}
// loop through every minute of this hour
for($m = 0; $m<=$minutes; $m++){
// add a zero in front of the first 9 minutes
if($m == 0){$m = '0'.$m;}
if($m == 00 || $m == 15 || $m == 30 || $m == 45){
// build current time to check for players
$thisTime = $h.':'.$m.':00';
// get players online at this time in this hour of chosen date
$get = $dbh->prepare("SELECT * FROM dcpmc_players_online WHERE time=? AND date=?");
$get->bindParam(1, $thisTime, PDO::PARAM_STR);
$get->bindParam(2, $chosenDate, PDO::PARAM_STR);
$get->execute();
$now = $get->fetchAll();
if(count($now) > 0){
foreach($now AS $index){
$hoverDate = $index['time'];
$playerExplode = explode(",", $index['players']);
if(count($playerExplode == 1)){
foreach($playerExplode AS $index){
if($index == 'none'){
$playerCount = 0;
}else{
$playerCount = count($playerExplode);
}
}
}
$left = $left+5;
$barHeight = $playerCount * 8; // 200px high container / 50 players = 8px per 1 player
echo '<div class="barContainer"><div class="bar1" style="height:'.$barHeight.'px;left:'.$left.'px;"></div>';
echo '<div class="hoverInfo"><p>'.$hoverDate.'</p><br />';
if($playerCount > 0){
echo '<p>'.$playerCount.' players online</p><br />';
foreach($playerExplode AS $index){
echo '<p>'.$index.' </p>';
}
}else{
echo '<p>No players online.</p>';
}
echo '</div>';
echo '</div>';
}
}
正如您所看到的,我正在使用for
循环来迭代每小时的每一分钟,我假设这会造成长时间的延迟。
Database表的结构如下所示:
答案 0 :(得分:2)
您可以执行一些操作,即在SELECT中替换*仅包含对查看者重要的字段。
您还可以构建数据库条目,以便在播放器登录时写入“条目记录”,并在注销时写入“退出记录”。这样,你每个会话只获得两个记录,而不是每个在线玩家每分钟1个。然后,您可以调整SELECT以计算该人是否具有该日的条目记录,并仅返回“是”值。同样,您可以让PHP找到会话条目并退出记录并显示该会话的各种信息。
如果你想确定他们已经开启并且没有断开连接,那么你也可以像现在一样每分钟进行一次检查,如果他们不在服务器上,但他们的最后一个条目是登录,那么输入注销记录,因为它们可能已断开连接并且未创建记录。
我还建议添加分配给每个条目和退出的会话ID,以使所有计算更容易。