Reputation: 95
Still a beginner so bear with me...
So I found this function for system uptime and have been fooling around with it as I learn about php and web development in general.
My goal is to have the output look like days:hours:mins:secs but there was no $seconds variable so I have added that line based on what else I had.
Everything works great except the seconds just shows up as 0. I'm not quite sure what I am doing wrong or if this is even the best way to do this.
function Uptime() {
$uptime = @file_get_contents( "/proc/uptime");
$uptime = explode(" ",$uptime);
$uptime = $uptime[0];
$days = explode(".",(($uptime % 31556926) / 86400));
$hours = explode(".",((($uptime % 31556926) % 86400) / 3600));
$minutes = explode(".",(((($uptime % 31556926) % 86400) % 3600) / 60));
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) / 60) / 60));
$time = $days[0].":".$hours[0].":".$minutes[0].":".$seconds[0];
return $time;
}
EDIT: I was able to get it working in a different way new function is below . I am also still curious if anyone can answer why the above method did not work as expected, and if the new method below is the best way to accomplish this.
function Uptime() {
$ut = strtok( exec( "cat /proc/uptime" ), "." );
$days = sprintf( "%2d", ($ut/(3600*24)) );
$hours = sprintf( "%2d", ( ($ut % (3600*24)) / 3600) );
$min = sprintf( "%2d", ($ut % (3600*24) % 3600)/60 );
$sec = sprintf( "%2d", ($ut % (3600*24) % 3600)%60 );
return array( $days, $hours, $min, $sec );
}
$ut = Uptime();
echo "Uptime: $ut[0]:$ut[1]:$ut[2]:$ut[3]";
EDIT 2: I believe this last method is the best based on the answer given by nwellnhof. I had to tweak a bit to get the output exactly as I wanted. Thanks guys.
function Uptime() {
$str = @file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = $num % 60;
$num = (int)($num / 60);
$mins = $num % 60;
$num = (int)($num / 60);
$hours = $num % 24;
$num = (int)($num / 24);
$days = $num;
return array(
"days" => $days,
"hours" => $hours,
"mins" => $mins,
"secs" => $secs
);
}
Upvotes: 8
Views: 21470
Reputation: 166429
On Unix/BSD, using /proc
is not reliable since it is not mounted by default, on some Linux distributions it can be unmounted also, so it's better to parse using either uptime
or sysctl
command, e.g.
sysctl
<?php
preg_match('/sec = (\d+)/', shell_exec('sysctl -n kern.boottime'), $secs)
echo $secs[1];
or:
$s = explode( " ", exec("/sbin/sysctl -n kern.boottime") );
$a = str_replace( ",", "", $s[3]);
$uptime = time() - $a;
or as per example taken from m0n0wall:
<?php
exec("/sbin/sysctl -n kern.boottime", $boottime);
preg_match("/sec = (\d+)/", $boottime[0], $matches);
$boottime = $matches[1];
$uptime = time() - $boottime;
if ($uptime > 60)
$uptime += 30;
$updays = (int)($uptime / 86400);
$uptime %= 86400;
$uphours = (int)($uptime / 3600);
$uptime %= 3600;
$upmins = (int)($uptime / 60);
$uptimestr = "";
if ($updays > 1)
$uptimestr .= "$updays days, ";
else if ($updays > 0)
$uptimestr .= "1 day, ";
$uptimestr .= sprintf("%02d:%02d", $uphours, $upmins);
echo htmlspecialchars($uptimestr);
uptime
Example taken from 4webhelp:
<?php
$data = shell_exec('uptime');
$uptime = explode(' up ', $data);
$uptime = explode(',', $uptime[1]);
$uptime = $uptime[0].', '.$uptime[1];
echo ('Current server uptime: '.$uptime.'
or (tested on FreeBSD):
$uptime = exec("uptime");
$uptime = split(" ",$uptime);
$days = $uptime[3]; # NetBSD: $days = $uptime[4];
$time = split(",",$uptime[5]); # NetBSD: $time = split(",",$uptime[7]);
if (sizeof($hourmin = split(":",$time[0])) < 2){ ;
$hours = "0";
$mins = $hourmin[0];
} else {
$hourmin=split(":",$time[0]);
$hours = $hourmin[0];
$mins = $hourmin[1];
}
$calcuptime = "Uptime: ".$days." days ".$hours." hours ".$mins." mins" ;
echo $calcuptime;
Here is version which works for Windows:
<?php
$uptime = `c:\windows\system32\uptime2.bat $server`;
$uptime = explode(": ", $uptime);
$uptime = explode(", ", $uptime[1]);
$uptime_days = preg_replace($pattern, '', $uptime[0]);
$uptime_hours = preg_replace($pattern, '', $uptime[1]);
$uptime_minutes = preg_replace($pattern, '', $uptime[2]);
$uptime_seconds = preg_replace($pattern, '', $uptime[3]);
echo '<b>Uptime:</b><br><br>';
echo 'Days: '.$uptime_days.'<br>';
echo 'Hours: '.$uptime_hours.'<br>';
echo 'Minutes: '.$uptime_minutes.'<br>';
echo 'Seconds: '.$uptime_seconds.'<br>';
Upvotes: 1
Reputation: 8075
variation of your initial example as a class:
class Uptime {
private $uptime;
private $modVals = array(31556926, 86400, 3600, 60, 60);
public function __construct() {
$this->read_uptime();
}
/**
* actually trigger a read of the system clock and cache the value
* @return string
*/
private function read_uptime() {
$uptime_raw = @file_get_contents("/proc/uptime");
$this->uptime = floatval($uptime_raw);
return $this->uptime;
}
private function get_uptime_cached() {
if(is_null($this->uptime)) $this->read_uptime(); // only read if not yet stored or empty
return $this->uptime;
}
/**
* recursively run mods on time value up to given depth
* @param int $d
* @return int
**/
private function doModDep($d) {
$start = $this->get_uptime_cached();
for($i=0;$i<$d;$i++) {
$start = $start % $this->modVals[$i];
}
return intval($start / $this->modVals[$d]);
}
public function getDays()
{
return $this->doModDep(1);
}
public function getHours() {
return $this->doModDep(2);
}
public function getMinutes()
{
return $this->doModDep(3);
}
public function getSeconds()
{
return $this->doModDep(4);
}
public function getTime($cached=false) {
if($cached != false) $this->read_uptime(); // resample cached system clock value
return sprintf("%03d:%02d:%02d:%02d", $this->getDays(), $this->getHours(), $this->getMinutes(), $this->getSeconds());
}
}
Upvotes: 1
Reputation: 14051
If you just look at the pattern in your statements, you can see that the one for seconds is different. It has two divisions. Additionally, the numbers you are using represent the number of seconds per time unit. The number of seconds per second should be 1, not 60. In short:
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) / 60) / 60));
Should be:
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) % 60) / 1));
Now this whole way of doing things is a bit weird. For example, (x % (n*m)) % m
is just x % m
.
A nicer way would be to do:
$uptime = (int) $uptime;
$seconds = $uptime % 60;
$minutes = ($uptime / 60 ) % 60;
$hours = ($uptime / (60*60) ) % 24;
$days = $uptime / (60*60*24); # % 365, if you want
Upvotes: 0
Reputation: 33638
Reading directly from /proc/uptime
is the most efficient solution on Linux. There are multiple ways to convert the output to days/hours/minutes/seconds. Try something like:
$str = @file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = fmod($num, 60); $num = (int)($num / 60);
$mins = $num % 60; $num = (int)($num / 60);
$hours = $num % 24; $num = (int)($num / 24);
$days = $num;
Or, with intdiv
(PHP7):
$str = @file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = fmod($num, 60); $num = intdiv($num, 60);
$mins = $num % 60; $num = intdiv($num, 60);
$hours = $num % 24; $num = intdiv($num, 24);
$days = $num;
Upvotes: 10
Reputation: 157990
uptime
supports the -p
command line option. You can use this simple piece of code:
echo shell_exec('uptime -p');
Upvotes: 4