The current script records the full web page address instead of total number of visits, resulting in a megabyte-sized file. This can be fixed by modifying the script to only store the total value of all addresses in the baz.dat file.
<?php
$total_data="baz.dat";
$real_data="real.dat";
$time=time();
$now=(int)(time()/86400);
$past_time=time()-600;
// Read and close the real data file
$readdata=fopen($real_data,"r") or die("Cannot open file $real_data");
$real_data_array=file($real_data);
fclose($readdata);
// Get user IP address
if(getenv('HTTP_X_FORWARDED_FOR'))
$user=getenv('HTTP_X_FORWARDED_FOR');
else
$user=getenv('REMOTE_ADDR');
// Iterate through the real data array
$d=count($real_data_array);
for($i=0;$i<$d;$i++)
{
list($live_user,$last_time)=explode("::","$real_data_array[$i]");
if($live_user!=""&&$last_time!=""):
if($last_time<$past_time):
$live_user="";
$last_time="";
endif;
if($live_user!=""&&$last_time!="")
{
if($user==$live_user)
{
$real_array[]="$user::$time\r\n";
}
else
$real_array[]="$live_user::$last_time";
}
endif;
}
// Check for user in real array
if(isset($real_array)):
foreach($real_array as $i=>$str)
{
if($str=="$user::$time\r\n")
{
$ok=$i;
break;
}
}
foreach($real_array as $j=>$str)
{
if($ok==$j) { $real_array[$ok]="$user::$time\r\n"; break;}
}
endif;
// Write to real data file
$writedata=fopen($real_data,"w") or die("Cannot open file $real_data");
flock($writedata,2);
if($real_array=="") $real_array[]="$user::$time\r\n";
foreach($real_array as $str)
fputs($writedata,"$str");
flock($writedata,3);
fclose($writedata);
// Read and close the total data file
$readdata=fopen($real_data,"r") or die("Cannot open file $real_data");
$real_data_array=file($real_data);
fclose($readdata);
$real=count($real_data_array);
// Write to total data file
$f=fopen($total_data,"a");
$call="$user|$now\n";
$call_size=strlen($call);
flock($f,2);
fputs($f, $call,$call_size);
flock($f,3);
fclose($f);
// Count hits and hosts for today and all time
$tarray=file($total_data);
$total_hits=count($tarray);
$today_hits_array=array();
for($i=0;$i<count($tarray);$i++)
{
list($ip,$t)=explode("|",$tarray[$i]);
if($now==$t) { array_push($today_hits_array,$ip); }
}
$today_hits=count($today_hits_array);
$total_hosts_array=array();
for($i=0;$i<count($tarray);$i++)
{
list($ip,$t)=explode("|",$tarray[$i]);
array_push($total_hosts_array,$ip);
}
$total_hosts=count(array_unique($total_hosts_array ));
$today_hosts_array=array();
for($i=0;$i<count($tarray);$i++)
{
list($ip,$t)=explode("|",$tarray[$i]);
if($now==$t) { array_push($today_hosts_array,$ip); }
}
$today_hosts=count(array_unique($today_hosts_array ));
?>
Storing the total number of visits in a file instead of the full address greatly reduces the file size and makes it more efficient. It is important for web developers to optimize their scripts to improve website performance.
Initially, it may seem impressive that a file has reached megabytes of records in just half a year. However, upon further inspection, this is actually not desirable. Just because something fulfills its intended purpose does not necessarily mean it does so effectively. In this particular case, the script used causes session locks and noticeable lag for all 150 online users due to the counter. Additionally, the code itself is poorly written, deterring sane developers from wanting to rewrite it.
With so many readily available solutions now, continuing to use a sluggish self-written program that stores an unnecessary amount of records seems illogical.
To prevent a user from being counted on subsequent visits, their IP can be entered into the database. There are several different approaches to accomplishing this. One possible method would be temporarily banning the counter during a user's session.
Another way to achieve this is to perform an insert into a separate cell when the page is first accessed and then use a SELECT request with a WHERE clause to check for the cell's existence upon future page views.
Here's the modified script that stores the total number of visits instead of the full web page addresses:
<?php
$total_data = "baz.dat";
$time = time();
$now = (int)(time() / 86400);
$past_time = time() - 600;
// Read and close the total data file
$readdata = fopen($total_data, "r") or die("Cannot open file $total_data");
$tarray = file($total_data);
fclose($readdata);
// Get user IP address
if (getenv('HTTP_X_FORWARDED_FOR'))
$user = getenv('HTTP_X_FORWARDED_FOR');
else
$user = getenv('REMOTE_ADDR');
// Update the total count for the user
$total_count = 0;
for ($i = 0; $i < count($tarray); $i++) {
list($ip, $t) = explode("|", $tarray[$i]);
if ($ip == $user) {
$total_count++;
}
}
// Write to total data file
$f = fopen($total_data, "w");
flock($f, 2);
$call = "$user|$now|$total_count\n";
$call_size = strlen($call);
fputs($f, $call, $call_size);
flock($f, 3);
fclose($f);
// Count hits and hosts for today and all time
$today_hits_array = array();
$today_hosts_array = array();
$total_hosts_array = array();
for ($i = 0; $i < count($tarray); $i++) {
list($ip, $t, $count) = explode("|", $tarray[$i]);
if ($now == $t) {
array_push($today_hits_array, $count);
array_push($today_hosts_array, $ip);
}
array_push($total_hosts_array, $ip);
}
$total_hits = array_sum($today_hits_array);
$today_hits = array_sum($today_hits_array);
$total_hosts = count(array_unique($total_hosts_array));
$today_hosts = count(array_unique($today_hosts_array));
?>
In this modified script, the `$real_data` file has been removed, and the script now only uses the `$total_data` file to store the total count of visits for each user. The file format has been changed to include the user IP, the day, and the total count of visits for that user.
The script now updates the total count for the user in the `$total_data` file, and the hit and host counts are calculated directly from the `$total_data` file. This reduces the file size significantly, as it no longer stores the full web page addresses.
The optimization you suggested is a good approach to improving the performance and efficiency of the script. By storing only the necessary information, the file size is reduced, and the script becomes more manageable and scalable.