代码之家  ›  专栏  ›  技术社区  ›  benizi vartec

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

php
  •  16
  • benizi vartec  · 技术社区  · 16 年前

    我想在PHP CLI中运行PHP CLI程序。在某些运行此功能的计算机上,同时安装了PHP4和PHP5。如果我运行外部程序

    php5 outer.php
    

    $^X 获取Perl可执行文件。在PHP中似乎没有这样的变量。

    $_SERVER['_'] ,因为Bash(和zsh)设置环境变量 $_

    更新: PATH 例如,如果不是在路径中找到的第一个版本,则查找版本信息的建议将毫无帮助。

    另外, csh 而变种似乎没有设定 $_ 环境变量,因此解决方法不适用于那里。

    更新2: 我用的是 xargs (这很有道理。。。 zsh 将其设置为运行的命令,即 参数代换 ,不是 php5

    $version = explode('.', phpversion());
    $phpcli = "php{$version[0]}";
    
    10 回复  |  直到 5 年前
        1
  •  39
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    值得注意的是,现在在php5.4+中可以使用预定义的常量 PHP_BINARY :

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

        2
  •  8
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

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

    $php_cmd = PHP_BIN_DIR.'/php' 指向我的PHP可执行文件。

        3
  •  4
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    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;
    
        4
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    好吧,这很难看,但它在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;
        }
    

    tasklist 可以提供可执行文件的名称,但不能提供可执行文件所在的完整路径。我只能找到一个给定PID的完整路径的例子 C++ AutoHotkey 诸如此类。如果有人对我还能去哪里有什么建议,请告诉我。

    附言:为了得到 PID 在PHP for Windows中,显然必须调用 getmypid()

        5
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

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

        6
  •  0
  •   jlh    5 年前

    对答案不满意后,我想出了自己的答案。它试图利用 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。

        7
  •  -1
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    findPHP()

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

        8
  •  -2
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    您可以尝试分析 phpinfo()

        9
  •  -3
  •   Peter Mortensen Pieter Jan Bonestroo    5 年前

    我认为最好的常数是 PHP_BINARY . 使用PHP5.5.12。

    推荐文章