5

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

lxg
  • 12,375
  • 12
  • 51
  • 73
Sithu
  • 4,752
  • 9
  • 64
  • 110
  • possible duplicate of [How do I interpret the output of php\_uname](http://stackoverflow.com/questions/21129737/how-do-i-interpret-the-output-of-php-uname) – kero Nov 11 '14 at 10:50
  • 1
    No, not a duplicate, because it asks for the distribution, not the platform. – lxg Nov 11 '14 at 11:13

3 Answers3

3

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

lxg
  • 12,375
  • 12
  • 51
  • 73
  • Thanks. Can you please add a web link for the function `glob`, e.g,. from php manual? And why you use it? Is there any advantage over the ordinary file/dir functions? – Sithu Nov 11 '14 at 11:38
  • And your code is not working. It issues `500 Internal Server Error`. – Sithu Nov 11 '14 at 11:44
  • https://php.net/glob … the 500 error may have been caused by the new array syntax. I have changed it to the old one (PHP < 5.4) now. If it still doesn't work, please check your error logs for the actual error message, or increase the error reporting level. – lxg Nov 11 '14 at 17:23
  • Yes, PHP in my server is 5.3. It seems working now, unfortunately it just output an empty array. Please [check here](http://sithukyaw.com/server2.php). It is not my ordinary server in this question, but same result. BTW, the link here is running on a sharing hosting where I found that `exec()` is working too. [Check it here](http://sithukyaw.com/server.php). – Sithu Nov 12 '14 at 04:22
  • `exec()` and `glob` are disabled in Web IDE like phpfiddle.org – Sithu Nov 12 '14 at 04:23
  • `exec` is indeed disabled on most hosts. `glob` however is available on most hosts; also, it's used by many common PHP applications. Instead of using `glob`, you could also check for the existence of the aforementioned files directly. – lxg Nov 12 '14 at 07:44
2

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

Community
  • 1
  • 1
Martin Fahl
  • 937
  • 2
  • 12
  • 28
-1

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

Community
  • 1
  • 1
Sithu
  • 4,752
  • 9
  • 64
  • 110
  • (1) Your command would return an error due to the duplicate `cat`. (2) See my answer for a pure PHP solution. Using `exec` here is bad, because if you want to maintain portability, you should avoid functions that are likely to be disabled on many hosts. – lxg Nov 11 '14 at 11:35
  • @lxg It did not return an error and it did work, though it was my typo. – Sithu Nov 11 '14 at 11:50
  • @lxg Thanks for your answer, but your solution gave me 500 error and nothing output. Please see my comment in your answer. In my experience, most of the time, `exec` does work in my servers, probably it is because of VPS with root access. It may not work in shared hostings as your concern. – Sithu Nov 11 '14 at 11:53