我想从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
答案 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。
答案 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
希望它有助于某人