使用 php exec 检查 npm 插件是否存在

Check if npm plugin exists with php exec

我有简单的 PHP 脚本来检查 npm 和 npm 插件。它通过命令行运行良好,但部分与 php exec.

$errors = '';
$outPut = null;
$exitCode = null;
exec('npm -v', $outPut, $exitCode); //<- this works
if($exitCode !== 0) {
    $errors = 'npm is not installed!';
    return false;
}
$outPut = null;
$exitCode = null;
exec('lessc -v', $outPut, $exitCode); //<- this works
if($exitCode !== 0) {
    $errors = 'lessc is not installed!';
    return false;
}

//check version of plugin: npm view/info less-plugin-autoprefix version
$outPut = null;
$exitCode = null;
exec('npm info less-plugin-autoprefix version', $outPut, $exitCode); //<- this not works !!!, $exitCode is 7 and $outPut is empty
if($exitCode !== 0) {
    $errors = 'lessc plugin autoprefix is not installed!';
    return false;
}

除命令 'npm info less-plugin-autoprefix version' 之外的所有作品。正如我在命令行中所说,它将 return 排除正确的结果。 我的代码有什么问题吗?

使用 exec 命令 npm info less-plugin-autoprefix version 2>&1 产生:

Array
(
    [0] => Error: Failed to replace env in config: ${APPDATA}
    [1] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:415:13
    [2] =>     at String.replace (<anonymous>)
    [3] =>     at envReplace (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:411:12)
    [4] =>     at parseField (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:389:7)
    [5] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:330:24
    [6] =>     at Array.forEach (<anonymous>)
    [7] =>     at Conf.add (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:328:23)
    [8] =>     at ConfigChain.addString (C:\Program Files\nodejs\node_modules\npm\node_modules\config-chain\index.js:244:8)
    [9] =>     at Conf.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:316:10)
    [10] =>     at C:\Program Files\nodejs\node_modules\npm\node_modules\graceful-fs\graceful-fs.js:115:16
    [11] => TypeError: Cannot read property 'loaded' of undefined
    [12] =>     at exit (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97:27)
    [13] =>     at errorHandler (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:216:3)
    [14] =>     at C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js:78:20
    [15] =>     at cb (C:\Program Files\nodejs\node_modules\npm\lib\npm.js:225:22)
    [16] =>     at C:\Program Files\nodejs\node_modules\npm\lib\npm.js:263:24
    [17] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:81:7
    [18] =>     at Array.forEach (<anonymous>)
    [19] =>     at Conf.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:80:13)
    [20] =>     at Conf.f (C:\Program Files\nodejs\node_modules\npm\node_modules\once\once.js:25:25)
    [21] =>     at emitOne (events.js:116:13)
    [22] => openssl config failed: error:02001002:system library:fopen:No such file or directory
    [23] => C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97
    [24] =>   var doExit = npm.config.loaded ? npm.config.get('_exit') : true
    [25] =>                           ^
    [26] => 
    [27] => TypeError: Cannot read property 'loaded' of undefined
    [28] =>     at exit (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97:27)
    [29] =>     at process.errorHandler (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:216:3)
    [30] =>     at emitOne (events.js:116:13)
    [31] =>     at process.emit (events.js:211:7)
    [32] =>     at process._fatalException (bootstrap_node.js:378:26)
    [33] => Error: Failed to replace env in config: ${APPDATA}
    [34] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:415:13
    [35] =>     at String.replace (<anonymous>)
    [36] =>     at envReplace (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:411:12)
    [37] =>     at parseField (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:389:7)
    [38] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:330:24
    [39] =>     at Array.forEach (<anonymous>)
    [40] =>     at Conf.add (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:328:23)
    [41] =>     at ConfigChain.addString (C:\Program Files\nodejs\node_modules\npm\node_modules\config-chain\index.js:244:8)
    [42] =>     at Conf.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:316:10)
    [43] =>     at C:\Program Files\nodejs\node_modules\npm\node_modules\graceful-fs\graceful-fs.js:115:16
    [44] => TypeError: Cannot read property 'loaded' of undefined
    [45] =>     at exit (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97:27)
    [46] =>     at errorHandler (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:216:3)
    [47] =>     at C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js:78:20
    [48] =>     at cb (C:\Program Files\nodejs\node_modules\npm\lib\npm.js:225:22)
    [49] =>     at C:\Program Files\nodejs\node_modules\npm\lib\npm.js:263:24
    [50] =>     at C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:81:7
    [51] =>     at Array.forEach (<anonymous>)
    [52] =>     at Conf.<anonymous> (C:\Program Files\nodejs\node_modules\npm\lib\config\core.js:80:13)
    [53] =>     at Conf.f (C:\Program Files\nodejs\node_modules\npm\node_modules\once\once.js:25:25)
    [54] =>     at emitOne (events.js:116:13)
    [55] => openssl config failed: error:02001002:system library:fopen:No such file or directory
    [56] => C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97
    [57] =>   var doExit = npm.config.loaded ? npm.config.get('_exit') : true
    [58] =>                           ^
    [59] => 
    [60] => TypeError: Cannot read property 'loaded' of undefined
    [61] =>     at exit (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:97:27)
    [62] =>     at process.errorHandler (C:\Program Files\nodejs\node_modules\npm\lib\utils\error-handler.js:216:3)
    [63] =>     at emitOne (events.js:116:13)
    [64] =>     at process.emit (events.js:211:7)
    [65] =>     at process._fatalException (bootstrap_node.js:378:26)
)

是否可以通过编程方式修复它? 我不知道它是否存在一些问题,但在命令行 'npm info less-plugin-autoprefix version' 中运行良好且没有错误。

将错误输出重定向到标准输出:

npm info less-plugin-autoprefix version 2>&1

这样,错误也将在 $outPut 数组中可用

经过一些实验,我得到了可行的解决方案。问题是 Windows 平台工作不同。

$c = get_defined_constants();
if(isset($c['PHP_OS']) && (strtoupper($c['PHP_OS']) === 'WINNT' || strtoupper($c['PHP_OS']) === 'WIN32')) {
    define('OS', 'WIN');
}
else {
    define('OS', 'LIN');
}
function array_search_partial($arr, $keyword) {
    foreach($arr as $index => $string) {
        if (strpos($string, $keyword) !== FALSE)
            return $string;
    }
}

$outPut = null;
$exitCode = null;
$appdata = getenv('APPDATA');
if(!$appdata) {
    if(OS === 'WIN') {
        $paths = $_SERVER['PATH'];
        if($paths) {
            //C:\Users\my_user_name\AppData\Roaming\npm
            $userPath = array_search_partial(explode(';', $paths), 'AppData\Roaming\npm');
            $userPath = mb_substr($userPath, 0, -4);
            putenv("APPDATA=$userPath");
        }
    }
    else {

    }

}

然后命令:

exec('npm info less-plugin-autoprefix version', $outPut, $exitCode);

按预期工作。