171

I have a PHP script that may be placed on a windows system or a linux system. I need to run different commands in either case.

How can I detect which environment I am in? (preferably something PHP rather than clever system hacks)

Update

To clarify, the script is running from the command line.

halfer
  • 19,824
  • 17
  • 99
  • 186
siliconpi
  • 8,105
  • 18
  • 69
  • 107
  • After performing benchmarks, it seems that any differences in performance between `\strncasecmp(\PHP_OS, 'WIN', 3) === 0`, `\strtoupper(\substr(\PHP_OS, 0, 3)) === 'WIN'` and `\stripos(\PHP_OS, 'WIN')` are below 15%. Since all three solutions only take roughly 100 nanoseconds, this would be a micro-optimization, anyway. So choose whatever solution you like. Finally, you may argue that `\strncasecmp(\PHP_OS, 'WIN', 3) === 0` is the most readable. – caw Aug 19 '19 at 23:26

13 Answers13

272

Check the value of the PHP_OS constantDocs.

It will give you various values on Windows like WIN32, WINNT or Windows.

See as well: Possible Values For: PHP_OS and php_unameDocs:

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    echo 'This is a server using Windows!';
} else {
    echo 'This is a server not using Windows!';
}
sanmai
  • 29,083
  • 12
  • 64
  • 76
Sander Marechal
  • 22,978
  • 13
  • 65
  • 96
  • What value would it be if it's Windows? There is nothing in the docs that I can see. – Shabbyrobe Jun 16 '11 at 04:48
  • 6
    Shabbyrobe: See http://stackoverflow.com/questions/738823/possible-values-for-php-os – Sander Marechal Jun 16 '11 at 13:05
  • 18
    `stripos(PHP_OS, 'WIN') === 0` can be used instead, arguably more readable / simple. – John Hunt Nov 09 '18 at 09:07
  • 1
    @dw1 - it would still work as it searches for "win" at the beginning. – John Hunt Nov 26 '18 at 12:12
  • 1
    And with php8 we now have `if (str_starts_with(strtoupper(PHP_OS), 'WIN')) {` – Redzarf Sep 15 '21 at 20:57
  • There is also a posix_uname() but it will not exist on some Windows environments. it will work in mingw/cygwin, but not in a dos/windows compiled php. Perhaps do a `if(function_exists('posix_uname'))` test before making a call to it. – Scott Jul 20 '22 at 15:17
  • @Shabbyrobe the value varies depending on the php installed. A windows/dos based php install will report something like 'WINNT'. Cygwin will return 'CYGWIN'. Not sure what mingw returns. – Scott Jul 20 '22 at 15:21
  • I've noticed also that some commands such as the 'uname' functions will return mixed case e.g. 'Windows'. So another way to check other than stripos would be `preg_match('/win/i', PHP_OS)` or `preg_match('/win/i', php_uname())`. If you want to be more specific, you can put search ^win as it's usually the first word in the result. But the non ^ version will also match 'CYGWIN' – Scott Jul 20 '22 at 15:24
82

You can check if the directory separator is / (for unix/linux/mac) or \ on windows. The constant name is DIRECTORY_SEPARATOR.

if (DIRECTORY_SEPARATOR === '/') {
    // unix, linux, mac
}

if (DIRECTORY_SEPARATOR === '\\') {
    // windows
}
StefansArya
  • 2,802
  • 3
  • 24
  • 25
Ibu
  • 42,752
  • 13
  • 76
  • 103
  • Unfortunately this does not work with Windows 7 and Zend Server. In this case DIRECTORY_SEPARATOR is also '\' – Achim Apr 15 '14 at 10:54
  • 4
    @Achim What do you mean? Zend Server is server software, not an OS. Windows 7 *should* return \. – mpen Aug 06 '14 at 17:41
  • 2
    `strpos(__FILE__,92)` exploits the same behaviour; `PATH_SEPARATOR>":"` returns true for Windows too (PATH_SEPARATOR is ":" on all other OSs). – Titus Jan 08 '17 at 12:45
  • 1
    Turned this into a function: `function is_linux(){return (DIRECTORY_SEPARATOR == '/') ? true : false;}` – Mario Lurig Oct 06 '17 at 00:25
41
if (strncasecmp(PHP_OS, 'WIN', 3) == 0) {
    echo 'This is a server using Windows!';
} else {
    echo 'This is a server not using Windows!';
}

seems like a bit more elegant than the accepted answer. The aforementioned detection with DIRECTORY_SEPARATOR is the fastest, though.

Ondřej Bouda
  • 1,061
  • 11
  • 16
  • Sorry, but this doesn't work right if you're using a Mac server, since in Mac you get a string that contains "DARWIN", which also contains "WIN", so in a Mac server you'll get "This is a server using Windows!" which is not true. – OMA Sep 28 '12 at 23:27
  • 15
    Well, this is not quite true. Notice that `strncasecmp` takes **the first** _n_ characters, not just any _n_ characters. If you tried it, you would have found out that `strncasecmp('DARWIN', 'WIN', 3) == 0` evaluates to `false`. – Ondřej Bouda Oct 14 '12 at 15:12
29

Starting with PHP 7.2.0 you can detect the running O.S. using the constant PHP_OS_FAMILY:

if (PHP_OS_FAMILY === "Windows") {
  echo "Running on Windows";
} elseif (PHP_OS_FAMILY === "Linux") {
  echo "Running on Linux";
}

See the official PHP documentation for its possible values.

josemmo
  • 6,523
  • 3
  • 35
  • 49
18

Note that PHP_OS reports the OS that PHP was built on, which is not necessarily the same OS that it is currently running on.

If you are on PHP >= 5.3 and just need to know whether you're running on Windows or not-Windows then testing whether one of the Windows-specific constants is defined may be a good bet, e.g.:

$windows = defined('PHP_WINDOWS_VERSION_MAJOR');
ejn
  • 189
  • 1
  • 2
  • 5
    1. Correct is not where PHP was built ON but for what it was built FOR 2. This applies to the defined windows related constant the same way... – StanE Sep 09 '14 at 11:43
  • 1
    Anyway PHP built for Windows can not be run on unix, can it? – Stalinko Dec 02 '16 at 08:11
9

According to Predefined Constants: User Contributed Notes Volker's and rdcapasso solution, you can simply create helper class like this:

<?php

class System {

    const OS_UNKNOWN = 1;
    const OS_WIN = 2;
    const OS_LINUX = 3;
    const OS_OSX = 4;

    /**
     * @return int
     */
    static public function getOS() {
        switch (true) {
            case stristr(PHP_OS, 'DAR'): return self::OS_OSX;
            case stristr(PHP_OS, 'WIN'): return self::OS_WIN;
            case stristr(PHP_OS, 'LINUX'): return self::OS_LINUX;
            default : return self::OS_UNKNOWN;
        }
    }

}

Usage:

if(System::getOS() == System::OS_WIN) {
  // do something only on Windows platform
}
Patryk Uszyński
  • 1,069
  • 1
  • 12
  • 20
9

The php_uname function can be used to detect this.

echo php_uname();
Anders Lindahl
  • 41,582
  • 9
  • 89
  • 93
8

This should work in PHP 4.3+:

if (strtolower(PHP_SHLIB_SUFFIX) === 'dll')
{
    // Windows
}
else
{
    // Linux/UNIX/OS X
}
Jonathon Hill
  • 3,445
  • 1
  • 33
  • 31
5

To detect whether it's Windows, OS X or Linux:

if (stripos(PHP_OS, 'win') === 0) {
    // code for windows
} elseif (stripos(PHP_OS, 'darwin') === 0) {
    // code for OS X
} elseif (stripos(PHP_OS, 'linux') === 0) {
    // code for Linux
}

stripos is a bit slower than substr in this particular case, yet it's efficient enough for such a small task, and more elegant.

artnikpro
  • 5,487
  • 4
  • 38
  • 40
  • Although the code is simple enough, this answer does not stand on its own: A great answer doesn't force one to read the question when coming from a search engine, because it is self-contained. – jpaugh Aug 15 '16 at 23:15
4

Core Predefined Constants: http://us3.php.net/manual/en/reserved.constants.php which has the PHP_OS (string) constant.

Or if you want to detect the OS of the client:

<?php
    echo $_SERVER['HTTP_USER_AGENT'] . "\n\n";

    $browser = get_browser(null, true);
    print_r($browser);
?>

From http://us3.php.net/manual/en/function.get-browser.php


According to your edit you can refer to this dublicate PHP Server Name from Command Line

You can use

string php_uname ([ string $mode = "a" ] )

So

php_uname("s")

's': Operating system name. eg. FreeBSD.

Would do the trick for you, see here http://php.net/manual/en/function.php-uname.php

Community
  • 1
  • 1
DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
3

You can check if a constant exists in PHP >5.3.0 (manual)

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
    // is Windows
}

Previously, this method was used in Symfony. Now they use a different method:

if ('\\' === DIRECTORY_SEPARATOR) {
    // is Windows
}
Michael Käfer
  • 1,597
  • 2
  • 19
  • 37
ghost404
  • 299
  • 2
  • 16
0

If you want to check if running under Linux, just test if (PHP_OS === 'Linux'). No need to use strtolower() and substr().

rtribaldos
  • 1,177
  • 14
  • 28
-2
function isWin(){
 if (strtolower(substr(PHP_OS, 0, 3)) === 'win' || PHP_SHLIB_SUFFIX == 'dll' || PATH_SEPARATOR == ';') {
    return true;
 } else {
    return false;
 }
}
Akam
  • 1,089
  • 16
  • 24