【问题标题】:Get the Linux distribution name in PHP在 PHP 中获取 Linux 发行版名称
【发布时间】:2015-01-07 21:19:56
【问题描述】:

PHP 中有没有办法找出远程服务器的 Linux 发行版名称?

$_SERVER['HTTP_USER_AGENT'] 中提取的只是客户端机器的操作系统名称。这不是我想要的。我试过php_uname()

echo 'Operating System: '.php_uname('s').'<br>'; // echo PHP_OS;
echo 'Release Name: '.php_uname('r').'<br>';
echo 'Version: '.php_uname('v').'<br>';
echo 'Machine Type: '.php_uname('m').'<br>';

但是s模式只返回内核类型——Linux。

Operating System: Linux
Release Name: 2.6.32-431.29.2.el6.x86_64
Version: #1 SMP Tue Sep 9 21:36:05 UTC 2014
Machine Type: x86_64

我想知道是Fedora、CentOS还是Ubuntu等。有可能吗?我也试过posix_uname(),但出错了。

致命错误:调用未定义的函数 posix_uname()

【问题讨论】:

标签: php linux operating-system linux-distro


【解决方案1】:

尝试 PHP system($call) 调用 http://php.net/manual/en/function.system.php 在那里,您可以在 ubuntu 系统上做任何您想做的事情来找出所需的信息,例如,您可能想要使用 system('cat /etc/issue'); 您可能想使用一种方法,从 PHP 调用 bash 脚本,例如 https://unix.stackexchange.com/questions/6345/how-can-i-get-distribution-name-and-version-number-in-a-simple-shell-script

【讨论】:

    【解决方案2】:

    The possible duplicate question 上面提到的查找发行版的成本很高。我使用exec() 并执行命令得到了一个快速简单的解决方案:

    $cmd = 'cat /etc/*-release';
    exec($cmd, $output);
    print_r($output);
    

    然后,结果。

    Array
    (
        [0] => CentOS release 6.6 (Final)
        [1] => CentOS release 6.6 (Final)
        [2] => CentOS release 6.6 (Final)
    )
    

    致谢:HowTo: Find Out My Linux Distribution Name and Version

    【讨论】:

    • (1) 由于cat 重复,您的命令将返回错误。 (2) 请参阅我对纯 PHP 解决方案的回答。在这里使用exec 是不好的,因为如果你想保持可移植性,你应该避免在许多主机上可能被禁用的功能。
    • @lxg 它没有返回错误并且确实有效,尽管这是我的错字。
    • @lxg 感谢您的回答,但您的解决方案给了我 500 错误并且没有输出。请在您的回答中查看我的评论。以我的经验,大多数时候,exec 确实在我的服务器上工作,可能是因为具有 root 访问权限的 VPS。它可能不适用于您担心的共享主机。
    【解决方案3】:

    在 Linux 系统上,通常有像 /etc/lsb-release/etc/os-release 这样的文件,其中包含有关分发的信息。

    您可以在 PHP 中读取它们并提取它们的值:

    if (strtolower(substr(PHP_OS, 0, 5)) === 'linux')
    {
        $vars = array();
        $files = glob('/etc/*-release');
    
        foreach ($files as $file)
        {
            $lines = array_filter(array_map(function($line) {
    
                // split value from key
                $parts = explode('=', $line);
    
                // makes sure that "useless" lines are ignored (together with array_filter)
                if (count($parts) !== 2) return false;
    
                // remove quotes, if the value is quoted
                $parts[1] = str_replace(array('"', "'"), '', $parts[1]);
                return $parts;
    
            }, file($file)));
    
            foreach ($lines as $line)
                $vars[$line[0]] = $line[1];
        }
    
        print_r($vars);
    }
    

    (不是最优雅的 PHP 代码,但它完成了工作。)

    这会给你一个像这样的数组:

    Array
    (
        [DISTRIB_ID] => Ubuntu
        [DISTRIB_RELEASE] => 13.04
        [DISTRIB_CODENAME] => raring
        [DISTRIB_DESCRIPTION] => Ubuntu 13.04
        [NAME] => Ubuntu
        [VERSION] => 13.04, Raring Ringtail
        [ID] => ubuntu
        [ID_LIKE] => debian
        [PRETTY_NAME] => Ubuntu 13.04
        [VERSION_ID] => 13.04
        [HOME_URL] => http://www.ubuntu.com/
        [SUPPORT_URL] => http://help.ubuntu.com/
        [BUG_REPORT_URL] => http://bugs.launchpad.net/ubuntu/
    )
    

    ID 字段最适合确定发行版,因为它由 Linux 标准库定义,并且应该出现在常见发行版中。

    顺便说一句,我建议不要使用exec()system() 来读取文件,因为出于安全原因,它们在许多服务器上被禁用。 (另外,它没有意义,因为PHP可以原生读取文件。如果它不能读取它们,那么通过系统调用也是不可能的。)

    【讨论】:

    • 谢谢。您能否为函数glob 添加一个网络链接,例如。从php手册?以及你为什么使用它?比普通的文件/目录函数有什么优势吗?
    • 你的代码不工作。它发出500 Internal Server Error
    • php.net/glob ... 500 错误可能是由新的数组语法引起的。我现在已将其更改为旧版本(PHP
    • 是的,我服务器中的 PHP 是 5.3。它现在似乎工作了,不幸的是它只输出一个空数组。请check here。在这个问题中,它不是我的普通服务器,而是相同的结果。顺便说一句,这里的链接在共享主机上运行,​​我发现exec() 也在工作。 Check it here.
    • exec()glob 在 Web IDE(如 phpfiddle.org)中被禁用
    猜你喜欢
    • 2012-10-17
    • 2011-09-13
    • 2011-02-14
    • 1970-01-01
    • 2011-05-19
    • 2013-02-07
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多