Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display system uptime in php?

Tags:

linux

php

php-5.5

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
        );
    }
like image 308
Ethan Morris Avatar asked Aug 11 '16 23:08

Ethan Morris


3 Answers

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;
like image 78
nwellnhof Avatar answered Oct 24 '22 09:10

nwellnhof


uptime supports the -p command line option. You can use this simple piece of code:

echo shell_exec('uptime -p');
like image 27
hek2mgl Avatar answered Oct 24 '22 10:10

hek2mgl


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());
    }
}
like image 1
Scott Avatar answered Oct 24 '22 08:10

Scott