【问题标题】:How to display system uptime in php?如何在php中显示系统正常运行时间?
【发布时间】:2016-08-11 23:23:43
【问题描述】:

还是个初学者,所以请耐心等待...
所以我发现了这个用于系统正常运行时间的功能,并且在我学习 php 和 web 开发的过程中一直在玩弄它。
我的目标是让输出看起来像 days:hours:mins:secs 但没有 $seconds 变量,所以我根据我拥有的其他内容添加了该行。 一切都很好,除了秒只显示为 0。我不太确定我做错了什么,或者这是否是最好的方法。

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;

}

编辑:我能够让它以不同的方式工作,新功能如下。 我仍然很好奇是否有人可以回答为什么上述方法没有按预期工作,以及下面的新方法是否是实现这一目标的最佳方法。

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]";

编辑 2:根据 nwellnhof 给出的答案,我相信最后一种方法是最好的。我必须稍微调整一下才能得到我想要的输出。谢谢各位。

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
        );
    }

【问题讨论】:

  • 取模 60 除以 60 将始终为
  • 31556926 的号码是从哪里得到的
  • 啊,是的,我试过了,然后忘记改回来会编辑我的帖子
  • 查看 PHP 中的 DateTime 类。 php.net/manual/en/book.datetime.php
  • @BlakeConnally 这个数字 31556926 似乎大致是一年中的秒数。

标签: php linux php-5.5


【解决方案1】:

直接从/proc/uptime 读取是Linux 上最有效的解决方案。有多种方法可以将输出转换为天/小时/分钟/秒。尝试类似:

$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;

或者,使用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;

【讨论】:

  • 只是出于好奇,为什么从 /proc/uptime 读取效率更高?
  • @EthanMorris 执行 uptimecat /proc/cpuinfo 会产生一个新进程(Unix 上的 fork/exec),这需要几毫秒。然后这个新进程读取/proc/cpuinfo 并将输出通过管道传回原始进程。直接读取/proc/cpuinfo 可以避免所有开销。
【解决方案2】:

uptime 支持-p 命令行选项。您可以使用这段简单的代码:

echo shell_exec('uptime -p');

【讨论】:

  • -s 参数到底有什么作用?
  • @EthanMorris 再看一遍,我认为它更像是您想要的-p 选项。
  • 有趣...当我尝试 -p 它给了我一个完全随机的日期,但是当我尝试 -s 它给了我当前日期和一个完全随机的时间。
  • 完全随机是什么意思?请注意,选项是不同的。 -p(漂亮)打印机器运行的时间。 -s 打印机器启动的时间。
  • 没关系我看错了 -p 输出是正确的,它只是在我的 html 中被切断了。
【解决方案3】:

作为一个类的初始示例的变体:

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());
    }
}

【讨论】:

  • 顺便说一句,现在在我自己的类库之一中 - 感谢您的领先!
【解决方案4】:

如果你只看你的陈述中的模式,你会发现几秒钟的模式是不同的。它有两个部门。此外,您使用的数字表示每个时间单位的秒数。每秒的秒数应该是 1,而不是 60。简而言之:

$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) / 60) / 60));

应该是:

$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) % 60) / 1));

现在整个做事方式有点奇怪。例如,(x % (n*m)) % m 就是 x % m

更好的方法是:

$uptime  = (int) $uptime;
$seconds =  $uptime               % 60;
$minutes = ($uptime /  60       ) % 60;
$hours   = ($uptime / (60*60)   ) % 24;
$days    =  $uptime / (60*60*24); # % 365, if you want

【讨论】:

  • 永远不要进行这样的计算,因为当夏令时发生变化时它们会出错。为此使用 PHP 的日期/时间函数。
  • @hek2mgl 从来不是强者;这取决于一个人想要什么以及如何使用它。此外,它应该是对 OP 的评论。这只是编写已发布内容的更好方式。
  • 我只是想诚实地学习,到目前为止的每个答案都有帮助。尽管@hek2mgl 确实对夏令时提出了一个很好的观点。
  • @hek2mgl 如果您只想转换为某种人类可读的持续时间,可以将一天定义为 24 小时(86,400 秒)。来自 GNU coreutils does the sameuptime 命令。
  • @nwellnhof 很有趣。我有来自 procps 而不是 coreutils 的uptime。该版本使用的是localtime(),它可以感知白天时间。
【解决方案5】:

在 Unix/BSD 上,使用 /proc 不可靠,因为它默认不挂载,在某些 Linux 发行版上它也可以卸载,因此最好使用 uptimesysctl 命令解析,例如

sysctl

<?php
preg_match('/sec = (\d+)/', shell_exec('sysctl -n kern.boottime'), $secs)
echo $secs[1];

或:

$s = explode( " ", exec("/sbin/sysctl -n kern.boottime") );
$a = str_replace( ",", "", $s[3]);
$uptime = time() - $a;  

或根据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

示例取自4webhelp:

<?php
$data = shell_exec('uptime');
$uptime = explode(' up ', $data);
$uptime = explode(',', $uptime[1]);
$uptime = $uptime[0].', '.$uptime[1];
echo ('Current server uptime: '.$uptime.'

或(在 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;

这是适用于 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>';

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多