从脚本中获取当前的PHP可执行文件?

时间:2010-03-03 15:41:20

标签: php

我想从PHP cli中运行PHP cli程序。在一些运行它的机器上,安装了php4和php5。如果我以

运行外部程序
php5 outer.php

我希望内部脚本使用相同的php版本运行。在Perl中,我将使用$^X来获取perl可执行文件。看来PHP中没有这样的变量吗?

现在,我正在使用$_SERVER['_'],因为bash(和zsh)将环境变量$_设置为最后运行的程序。但是,我宁愿不依赖于特定于shell的习语。

更新:版本差异只是一个问题。例如,如果PHP不在PATH中,或者不是PATH中的第一个版本,那么查找版本信息的建议将无济于事。

此外,csh和变体似乎没有为其进程设置$_环境变量,因此解决方法在那里不适用。

更新2:我正在使用$_SERVER['_'],直到我发现它在xargs下没有做正确的事情(这是有道理的...... {{1将它设置为它运行的命令,zsh,而不是xargs,而php5不会更改变量)。回归使用:

xargs

11 个答案:

答案 0 :(得分:32)

值得注意的是,现在在PHP 5.4+中你可以使用预定义的常量 - PHP_BINARY

  

PHP_BINARY

     

指定脚本执行期间的PHP二进制路径。从PHP 5.4开始提供。

答案 1 :(得分:8)

在我的服务器上我有php 5.3.14。

我找到了一个预定义的常量:PHP_BIN_DIR

然后,假设可执行文件的文件名始终为'php',$php_cmd = PHP_BIN_DIR.'/php'指向我的PHP可执行文件。

答案 2 :(得分:3)

好的,所以这很难看,但它适用于Linux:

<?php
    // Returns the full path of the current PHP executable
    function get_proc_name(){
       // Gets the PID of the current executable
       $pid = posix_getpid();

       // Returns the exact path to the PHP executable.
       $exe = exec("readlink -f /proc/$pid/exe");
       return $exe;
    }

我稍后会尝试使用Windows版本。

修改

看起来没有任何简单的方法可以为Windows执行此操作。某些Windows可执行文件(如tasklist)可以为您提供可执行文件的名称,但不是可执行文件所在的完整路径。我只能找到给出C++,AutoHotkey等PID的完整路径的示例。如果有人对我可以看到的其他地方有任何建议,请告诉我。

PS:要在PHP for PHP中获取PID,您显然必须调用getmypid()

答案 3 :(得分:2)

在执行“内部”脚本之前,您可以使用phpversion()来获取当前版本的PHP。

http://php.net/manual/en/function.phpversion.php

答案 4 :(得分:2)

不幸的是,PHP_BINARY正在返回httpd二进制文件(在Windows XAMPP上),所以我回到使用路径......

    if (defined('PHP_BINARY') && PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server')) && is_file(PHP_BINARY)) {
          return PHP_BINARY;
    } else if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        $paths = explode(PATH_SEPARATOR, getenv('PATH'));
        foreach ($paths as $path) {
            if (substr($path, strlen($path)-1)==DIRECTORY_SEPARATOR) {
                $path=substr($path, 0, strlen($path)-1);
            }
            if ( substr($path, strlen($path) - strlen('php')) == 'php' ) {
                $response=$path.DIRECTORY_SEPARATOR.'php.exe';
                if (is_file($response)) {
                    return $response;
                }
            } else if ( substr($path, strlen($path) - strlen('php.exe')) == 'php.exe' ) {
                if (is_file($response)) {
                    return $response;
                }
            }                
        }
    } else {
        $paths = explode(PATH_SEPARATOR, getenv('PATH'));
        foreach ($paths as $path) {
            if (substr($path, strlen($path)-1)==DIRECTORY_SEPARATOR) {
                $path=substr($path, strlen($path)-1);
            }
            if ( substr($path, strlen($path) - strlen('php')) == 'php' ) {
                if (is_file($path)) {
                    return $path;
                }
                $response=$path.DIRECTORY_SEPARATOR.'php';
                if (is_file($response)) {
                    return $response;
                }
            }               
        }
    }
    return null;

答案 5 :(得分:1)

$_ENV中有什么用处吗?

Unix上的SHELL环境变量具有当前正在运行的shell的路径。如果您将#!/path/to/php添加到PHP文件的顶部,将其设置为可执行文件并直接运行该文件,$_ENV['SHELL']是否包含/path/to/php

答案 6 :(得分:0)

这个答案有助于追踪php位置: How to get the path of the PHP BIN from PHP?

它也是windows和linux友好的:)

答案 7 :(得分:0)

在对答案不满意后,我想出了自己的答案。如果看起来合理,它会尝试使用 PHP_BINARY,否则它会寻找与当前运行的解释器版本相同的解释器。

/**
 * Return a suitable PHP interpreter that is likely to be the same version as the
 * currently running interpreter.  This is similar to using the PHP_BINARY constant, but
 * it will also work from within mod_php or PHP-FPM, in which case PHP_BINARY will return
 * unusable interpreters.
 *
 * @return string
 */
public function getPhpInterpreter(): string {
    static $cachedExecutable = null;

    if ($cachedExecutable !== null) {
        return $cachedExecutable;
    }

    $basename = basename(PHP_BINARY);

    // If the binary is 'php', 'php7', 'php7.3' etc, then assume it's a usable interpreter
    if ($basename === 'php' || preg_match('/^php\d+(?:\.\d+)*$/', $basename)) {
        return PHP_BINARY;
    }

    // Otherwise, we might be running as mod_php, php-fpm, etc, where PHP_BINARY is not a
    // usable PHP interpreter.  Try to find one with the same version as the current one.

    $candidates = [
        'php' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION,
        'php' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
        'php' . PHP_MAJOR_VERSION,
    ];

    $envPath = $_SERVER['PATH'] ?? '';
    $paths = $envPath !== '' ? explode(':', $envPath) : [];

    if (!in_array(PHP_BINDIR, $paths, true)) {
        $paths[] = PHP_BINDIR;
    }

    foreach ($candidates as $candidate) {
        foreach ($paths as $path) {
            $executable = $path . DIRECTORY_SEPARATOR . $candidate;
            if (is_executable($executable)) {
                $cachedExecutable = $executable;
                return $executable;
            }
        }
    }

    // Fallback, if nothing else can be found
    $cachedExecutable = 'php';
    return $cachedExecutable;
}

让我知道这是否适合您。我在 Debian Buster、CLI 和 FPM 上对其进行了测试。

答案 8 :(得分:-2)

您可以尝试解析phpinfo()结果。

答案 9 :(得分:-2)

我认为最好的常量PHP_BINARY。使用PHP 5.5.12

答案 10 :(得分:-2)

我知道这个问题有点老了,但是在寻找更短的方法的时候出现了。

不幸的是,我找不到更短的方法,但这种方法效果很好,兼容多OS / PHP版本。

$ lookIn可能会扩展到包含更常见的位置。

https://gist.github.com/cjsewell/39b60065ae2af677ceb1

希望它有助于某人