如何在php中生成一个新进程来调用需要子进程的节点脚本


How to spawn a new process in php to call a node script that requires a child process

我试图在隔离中运行PHP代码。php代码只是以所需的参数间隔调用节点脚本。另一方面,Node.js脚本计算参数以从mongoDb获取额外数据,然后在其中生成一个子进程,使用这些参数调用Phantomjs并创建热图图像文件。

现在,当使用正确的参数从命令行触发时,Node.js脚本运行良好。

但是无论我怎么尝试,当从php调用时,我都无法让它工作。

我已经尝试了shell_exec和exec如下:

$node = '/usr/local/bin/node';
$scriptPath = $this->basePath . '/web/scripts/node/heatmaps_node_wrapper.js';
$clickmapCmd = $node . ' ' . $scriptPath . ' ' . $url . ' ' . $groupId . ' ' . $heatmapId . ' click';
$mousemovemapCmd = $node . ' ' . $scriptPath . ' ' . $url . ' ' . $groupId . ' ' . $heatmapId . ' mousemove';
$asyncCmd = ' >' . $this->basePath . '/logs/heatmap.io.log 2>'. $this->basePath . '/logs/heatmap.err.log &';
exec($clickmapCmd . $asyncCmd);
exec($mousemovemapCmd . $asyncCmd);

也尝试使用symfony的ProcessBuilder组件,像这样-

$builder = new ProcessBuilder();
$builder->setPrefix('/usr/local/bin/node');
$builder->setArguments(array($scriptPath, $url, $groupId, $heatmapId, 'click'));
$process = $builder->getProcess();
$process->setTimeout(1000);
$process->setIdleTimeout(1000);
$process->start();
$output = $process->getOutput();

都无法创建热图图像。

但是调试symfony代码和研究symfony的Process对象帮助我发现了可能的问题。在对象标准中,我看到以下消息-

events.js:85
  throw er; // Unhandled 'error' event
        ^
Error: spawn phantomjs ENOENT
at exports._errnoException (util.js:746:11)
at Process.ChildProcess._handle.onexit (child_process.js:1053:32)
at child_process.js:1144:20
at process._tickCallback (node.js:355:11)

所以我猜问题是Node试图创建PHP子进程的子进程(?? ?)。

所以我的问题是,这个问题的解决方案是什么?

干杯!

问题是节点找不到phantomjs。如果它不在执行节点脚本的用户的$PATH中,您可以尝试使用phantomjs二进制文件的完整路径。您可能还想检查phantomjs二进制文件的可执行权限。