PHP脚本 - 检测当前运行环境是否为Linux或Windows?

171

我有一个 PHP 脚本,它可能被放置在 Windows 系统或 Linux 系统上。我需要在任一情况下运行不同的命令。

如何检测我所处的环境?(最好是使用 PHP 而不是 clever system hacks)

更新

澄清一下,该脚本是从命令行运行的。


经过性能基准测试,似乎\strncasecmp (\PHP_OS,'WIN',3)===0\strtoupper(\substr(\PHP_OS,0,3))== = 'WIN'\stripos(\PHP_OS,'WIN')之间的性能差异都在15%以下。由于这三种解决方案只需要大约100纳秒的时间,这将是微观优化。因此,请选择您喜欢的任何解决方案。最后,您可以认为\strncasecmp(\PHP_OS,'WIN',3)===0是最易读的。 - caw
13个回答

273

检查PHP_OS常量文档的值。

在Windows上,它会给你不同的值,例如WIN32WINNTWindows

也可以参考:可能的值:PHP_OSphp_uname文档

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    echo 'This is a server using Windows!';
} else {
    echo 'This is a server not using Windows!';
}

如果它是Windows,那会有什么价值呢?文档中没有我能看到的内容。 - Shabbyrobe
6
破旧的长袍(Shabbyrobe):请见https://dev59.com/H3RB5IYBdhLWcg3wCjnO - Sander Marechal
18
可以使用stripos(PHP_OS, 'WIN') === 0来代替,它可能更易读/简单。 - John Hunt
1
@dw1 - 它仍然可以工作,因为它在开头搜索“win”。 - John Hunt
1
而且在 PHP8 中,我们现在有了 if (str_starts_with(strtoupper(PHP_OS), 'WIN')) { - Redzarf
显示剩余3条评论

82

您可以检查目录分隔符是/(适用于Unix / Linux / macOS)还是\(适用于Windows)。常量名称为DIRECTORY_SEPARATOR

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

if (DIRECTORY_SEPARATOR === '\\') {
    // windows
}

不幸的是,这在Windows 7和Zend Server上无法运行。在这种情况下,DIRECTORY_SEPARATOR也是''。 - Achim
4
@Achim 你的意思是什么?Zend Server是服务器软件,而不是操作系统。Windows 7 应该 返回 \。 - mpen
2
strpos(__FILE__,92) 利用了相同的行为; PATH_SEPARATOR>":" 在 Windows 上也返回 true(在所有其他操作系统上,PATH_SEPARATOR 都是“:”)。 - Titus
1
将其转换为一个函数:function is_linux(){return (DIRECTORY_SEPARATOR == '/') ? true : false;} - Mario Lurig

41
if (strncasecmp(PHP_OS, 'WIN', 3) == 0) {
    echo 'This is a server using Windows!';
} else {
    echo 'This is a server not using Windows!';
}

看起来比被接受的答案更加优雅。不过前面提到使用 DIRECTORY_SEPARATOR 进行检测是最快的。


抱歉,如果您使用的是Mac服务器,这将无法正常工作,因为在Mac中,您会得到一个包含“DARWIN”的字符串,该字符串也包含“WIN”,因此在Mac服务器上,您将得到“这是一个使用Windows的服务器!”这是不正确的。 - OMA
15
这不完全正确。请注意 strncasecmp 只取前 n 个字符,而不是任意 n 个字符。如果尝试过的话,你会发现 strncasecmp('DARWIN', 'WIN', 3) == 0 的结果是 false - Ondřej Bouda

29
从 PHP 7.2.0 开始,您可以使用常量 PHP_OS_FAMILY 检测正在运行的操作系统。
if (PHP_OS_FAMILY === "Windows") {
  echo "Running on Windows";
} elseif (PHP_OS_FAMILY === "Linux") {
  echo "Running on Linux";
}

请参考官方PHP文档以获得其可能的值。


1
@Stef 根据 3v4l,它只在 PHP 7.2 中可用 https://3v4l.org/CBpG4 - Lucas Bustamante
鉴于几乎每个人都应该使用PHP版本7.2+,这是最优雅的答案。 - James John McGuire 'Jahmic'
由于几乎每个人都应该使用 PHP 7.2+ 版本,这是最优雅的答案。 - James John McGuire 'Jahmic'

18

请注意,PHP_OS报告的是PHP编译时所使用的操作系统,并不一定是当前正在运行的操作系统。

如果你使用的是 PHP >= 5.3,并且只需要知道自己是否正在运行在 Windows 或非 Windows 系统上,那么测试一个Windows专用常量是否已定义也许是个好选择,例如:

$windows = defined('PHP_WINDOWS_VERSION_MAJOR');

5
  1. 正确的理解是 PHP 被构建的目的,而不是它建立在哪里。
  2. 这同样适用于已定义的与 Windows 相关的常量...
- StanE
1
无论如何,为Windows构建的PHP不能在Unix上运行,对吧? - Stalinko

10
根据预定义常量:用户贡献注释 Volker和rdcapasso的解决方案,你可以简单地创建一个辅助类,就像这样:
<?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;
        }
    }

}

用法:

if(System::getOS() == System::OS_WIN) {
  // do something only on Windows platform
}

9

可以使用php_uname函数来检测这个。

echo php_uname();

8

这应该适用于PHP 4.3+:

if (strtolower(PHP_SHLIB_SUFFIX) === 'dll')
{
    // Windows
}
else
{
    // Linux/UNIX/OS X
}

5

检测操作系统是Windows、OS X还是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在这种情况下比substr略慢,但对于如此小的任务来说足够高效,而且更加优雅。


尽管代码足够简单,但这个答案并不独立存在:一个好的答案不会强制读者在从搜索引擎跳转过来时阅读问题,因为它是自包含的。 - jpaugh

4
您可以在PHP>5.3.0中检查常量是否存在(手册)。
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
    // is Windows
}

此前,Symfony使用了这种方法。现在他们使用不同的方法

if ('\\' === DIRECTORY_SEPARATOR) {
    // is Windows
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接