Get the Linux distribution name in PHP

5.1k Views Asked by At

Is there a way in PHP to figure out the Linux distribution name of a remote server?

Extracting from $_SERVER['HTTP_USER_AGENT'] is just the OS name of the client's machine. It is not what I want. I tried 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>';

But the mode s returns only the kernel type - 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

I want to know it is Fedora, CentOS or Ubuntu, etc. Is it possible? I have also tried posix_uname(), but got an error.

Fatal error: Call to undefined function posix_uname()

4

There are 4 best solutions below

0
On

Try a PHP system($call) call http://php.net/manual/en/function.system.php There you can do whatever you want to find out the desired infomation, on an ubuntu system, you might for example want to use system('cat /etc/issue'); You might want to use an approach, where you call a bash script from PHP, for example https://unix.stackexchange.com/questions/6345/how-can-i-get-distribution-name-and-version-number-in-a-simple-shell-script

3
On

The possible duplicate question mentioned above is expensive to find out the distributions. I got a quick and simple solution using exec() and executing the command:

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

then, it results.

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

Credits: HowTo: Find Out My Linux Distribution Name and Version

6
On

On a Linux system, there are usually files like /etc/lsb-release or /etc/os-release which contain information about the distribution.

You can read them in PHP and extract their values:

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

(Not the most elegant PHP code, but it gets the job done.)

This will give you an array like:

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/
)

The ID field is best suited to determine the distribution, as it's defined by the Linux Standard Base and should be present on common distributions.

By the way, I would recommend not using exec() or system() to read files, because they are disabled on many servers for security reasons. (Also, it doesn't make sense, because PHP can natively read files. And if it can't read them, then it also won't be possible though a system call.)

1
On

You will need to make system calls and the commands or locations of where that info can be obtained can vary by distro. Here is code that queries the most common locations in a cascading fashion until it finds the answer:

$linux_distro = null;
$os_info = file_exists("/etc/os-release") ? explode("\n", shell_exec("cat /etc/os-release")) : [];
foreach ($os_info as $line) {
    if (preg_match('/^ID=(")?[a-zA-Z]+(")?/i', trim($line))) {
        $linux_distro = strtolower(preg_replace('/(^ID=(")?|")/i', "", trim($line)));
        break;
    }
}
if (!$linux_distro) {
    $hostnamectl_available = shell_exec("command -v hostnamectl");
    $os_info = ($hostnamectl_available) ? explode("\n", shell_exec("hostnamectl")) : [];
    foreach ($os_info as $line) {
        if (preg_match('/^Operating System:\s+/i', trim($line))) {
            $linux_distro = strtolower(preg_replace('/(^Operating System:\s+)([\w]+)\b(.*)?/i', "$2", trim($line)));
            break;
        }
    }
}
if (!$linux_distro) {
    $lsb_release_available = shell_exec("command -v lsb_release");
    $os_info = ($lsb_release_available) ? explode("\n", shell_exec("lsb_release -a")) : [];
    foreach ($os_info as $line) {
        if (preg_match('/^Distributor ID:\s+/i', trim($line))) {
            $linux_distro = strtolower(preg_replace('/(^Distributor ID:\s+)([\w]+)\b(.*)?/i', "$2", trim($line)));
            break;
        }
    }
}
if (!$linux_distro) {
    $os_info = file_exists("/etc/system-release") ? shell_exec("cat /etc/system-release") : "";
    $linux_distro = ($os_info) ? strtolower(preg_replace('/^([\w]+)\b(.*)?/', "$1", trim($os_info))) : "not found";
}
if (preg_match('/^(red|redhatlinux|rhel|redhatenterpriseserver|redhatenterpriselinux)$/', $linux_distro))
    $linux_distro = "redhat";