[英]Call PHP-CLI script without Shell from PHP
我想從我的 PHP 腳本運行 Composer 的一些供應商腳本。
盡管命令本身很快完成,但調用每個命令都需要很長時間。 我假設通過shell_exec()
創建一個新的 shell 需要一些時間。
我想通過require
關鍵字直接調用 PHP 腳本,但更改全局$argv
以包含腳本參數不適用於被調用的腳本。 $argv
是跨腳本文件隱式不可變的還是我的思維方式有另一個錯誤?
下面是一些示例代碼(應通過 CLI 執行,未經測試):
namespace Foo;
class Bar
{
public static function call_cs_fixer()
{
$GLOBALS['argv'] = [
'/path/to/vendor/bin/php-cs-fixer',
'fix',
'--config',
'"/path/to/.php-cs-fixer.php"',
'"/path/to/project"',
];
return require $GLOBALS['argv'][0];
}
}
echo \Foo\Bar::call_cs_fixer();
$argv
是跨腳本文件隱式不可變的還是我的思維方式有另一個錯誤?
這取決於您嘗試調用的腳本/實用程序的工作方式。 這意味着你不能指望它能穩定地工作,除非你知道它有這個界面,否則我會避免使用它。 因為你不知道——否則你不會那樣問這個問題——在這種情況下把這個想法扔進垃圾箱。
我假設通過
shell_exec()
創建一個新的 shell 需要一些時間。
這可能是(我們無法查看您的系統配置),但如果它是 linux 系統,則很可能不是這種情況。
在實踐中,使用新的 shell 子流程來調用工具是更好的方法。 這也是composer(1)
調用腳本的方式(請參閱腳本)——除非它們被綁定為(靜態)方法——並且對於composer exec
命令始終如此。
原因是您不僅可以更好地控制命令行 arguments,還可以更好地控制工作目錄和環境參數(簡稱環境變量或環境),比較proc_open(php)
。 標准流也可用。
當您在 composer 的上下文中運行時,如果您可以訪問它的源代碼(例如,您在 composer.json 配置中綁定了一個 composer 腳本或掛鈎),您可以使用 composer 本身附帶的流程組件(它的所有 PHP),它在那里有相當多的實用性。
如果你只是想輕松開始,我發現passthru(php)
function 非常適合快速入門:
// the command you'd like to execute
$command = '/path/to/vendor/bin/php-cs-fixer';
$args = [
'fix',
'--config',
'/path/to/.php-cs-fixer.php',
'/path/to/project'
];
// build the command-line
$commandLine = sprintf(
'%s %s',
$command,
implode(' ', array_map('escapeshellarg', $args))
);
// execute
$result = passthru($commandLine, $exitStatus);
// be verbose and give some debug info
fprintf(
STDERR,
"debug: command %s exited with status %d\n",
$commandLine,
$exitStatus
);
// throw on exit status != 0, a convention only but you often want this
if (false === $result || $existStatus !== 0) {
throw new \RuntimeException(sprintf(
'command "%s" exited with non-zero status %d (result=%s).\n',
addcslashes($commandLine, "\0..\37\"\\\177..\377"),
$exitStatus,
var_export($result, true)
), (int)$exitStatus);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.