Javascript 在CLI和node.js脚本中运行时,执行PHP脚本的结果不同
我完全搞不明白为什么我的PHP脚本在通过CLI运行时(产生正确的结果)与在Node.js中通过exec函数运行时产生不同的结果 这是我的PHP。注意Javascript 在CLI和node.js脚本中运行时,执行PHP脚本的结果不同,javascript,php,node.js,exec,command-line-interface,Javascript,Php,Node.js,Exec,Command Line Interface,我完全搞不明白为什么我的PHP脚本在通过CLI运行时(产生正确的结果)与在Node.js中通过exec函数运行时产生不同的结果 这是我的PHP。注意fopen('blah.txt','w')行,这是我用来检查脚本是否到达该位置的 calculator.php class calculator{ public static $_var = array(); public function calculate($xml, $xsl, $frequency){ $r
fopen('blah.txt','w')
行,这是我用来检查脚本是否到达该位置的
calculator.php
class calculator{
public static $_var = array();
public function calculate($xml, $xsl, $frequency){
$reader = new DOMDocument;
if(!$reader->load($xsl)) throw new Exception('XSL Could not be loaded: ' . $xsl);
$processor = new XSLTProcessor;
$processor->importStyleSheet($reader);
$processor->registerPHPFunctions();
$processor->setParameter('', 'frequency', $frequency);
$dictionary = new DOMDocument;
if(!$dictionary->load($xml)) throw new Exception('XML Could not be loaded: ' . $xml);
$processor->transformToXML($dictionary);
}
public static function connectNodes($name, $dataset, $processor, $destination, $frequency){
$var = self::$_var;
self::$_var = array();
$test = fopen('blah.txt', 'w');
fclose($test);
ob_start();
require 'templates/' . $processor . '.php';
$xsltSheet = new DOMDocument;
$xsltSheet->loadXML(ob_get_clean());
$xsltProc = new XSLTProcessor;
$xsltProc->importStyleSheet($xsltSheet);
$dataSet = new DOMDocument;
if(is_file('../dataFiles/xml/' . $dataset . '.xml') && calculator::makedirs('../dataFiles/json/' . $destination . '/' . $frequency)){
//proceed only if the dataset exists and the folders are created correctly
$dataSet->load('../dataFiles/xml/' . $dataset . '.xml');
if(!is_file('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json')){
$filemaker = fopen('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json', 'w');
fclose($filemaker);
}
$xsltProc->transformToURI($dataSet, '../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json');
} else {
throw new Exception('Either dataset does not exist('. $dataset .'), or directories could not be created (dataFiles/json/'. $destination . '/' . $frequency .')');
}
}
public static function populateVarWithXPath($var){
self::$_var[] = $var;
}
public static function makedirs($dirpath, $mode=0777) {
return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}
}
当我通过CLI运行此脚本时,会在运行脚本的目录中创建blah.txt。但是当我通过Node.js运行它时,它不会创建blah.txt
以下是我的节点脚本:
脚本运行程序
class calculator{
public static $_var = array();
public function calculate($xml, $xsl, $frequency){
$reader = new DOMDocument;
if(!$reader->load($xsl)) throw new Exception('XSL Could not be loaded: ' . $xsl);
$processor = new XSLTProcessor;
$processor->importStyleSheet($reader);
$processor->registerPHPFunctions();
$processor->setParameter('', 'frequency', $frequency);
$dictionary = new DOMDocument;
if(!$dictionary->load($xml)) throw new Exception('XML Could not be loaded: ' . $xml);
$processor->transformToXML($dictionary);
}
public static function connectNodes($name, $dataset, $processor, $destination, $frequency){
$var = self::$_var;
self::$_var = array();
$test = fopen('blah.txt', 'w');
fclose($test);
ob_start();
require 'templates/' . $processor . '.php';
$xsltSheet = new DOMDocument;
$xsltSheet->loadXML(ob_get_clean());
$xsltProc = new XSLTProcessor;
$xsltProc->importStyleSheet($xsltSheet);
$dataSet = new DOMDocument;
if(is_file('../dataFiles/xml/' . $dataset . '.xml') && calculator::makedirs('../dataFiles/json/' . $destination . '/' . $frequency)){
//proceed only if the dataset exists and the folders are created correctly
$dataSet->load('../dataFiles/xml/' . $dataset . '.xml');
if(!is_file('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json')){
$filemaker = fopen('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json', 'w');
fclose($filemaker);
}
$xsltProc->transformToURI($dataSet, '../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json');
} else {
throw new Exception('Either dataset does not exist('. $dataset .'), or directories could not be created (dataFiles/json/'. $destination . '/' . $frequency .')');
}
}
public static function populateVarWithXPath($var){
self::$_var[] = $var;
}
public static function makedirs($dirpath, $mode=0777) {
return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}
}
var ipc = require('./ipc');
var exec = require('child_process').exec;
ipc.listen(function(frequency){
if(frequency.toString().match(/integrator /)){
var freq = frequency.toString().replace(/integrator /, '');
console.log('Received message: ' + freq);
var cmd = exec('php use_calculator.php metricsDictionary.xml metricsXmlReader.xsl ' + frequency);
cmd.on('close', function(exitCode, stdout, stderr){
if(exitCode === 0){
console.log('exitcode: ' + exitCode + ' ; stdout: ' + stdout + ' ; stderr: ' + stderr);
} else {
console.log('Try again?');
}
});
cmd.on('error', function(err){
throw err;
});
}
});
有趣的是,如果我将blah.txt移到calculate()函数(首先运行),CLI和node都将创建该文件
多一点背景:
class calculator{
public static $_var = array();
public function calculate($xml, $xsl, $frequency){
$reader = new DOMDocument;
if(!$reader->load($xsl)) throw new Exception('XSL Could not be loaded: ' . $xsl);
$processor = new XSLTProcessor;
$processor->importStyleSheet($reader);
$processor->registerPHPFunctions();
$processor->setParameter('', 'frequency', $frequency);
$dictionary = new DOMDocument;
if(!$dictionary->load($xml)) throw new Exception('XML Could not be loaded: ' . $xml);
$processor->transformToXML($dictionary);
}
public static function connectNodes($name, $dataset, $processor, $destination, $frequency){
$var = self::$_var;
self::$_var = array();
$test = fopen('blah.txt', 'w');
fclose($test);
ob_start();
require 'templates/' . $processor . '.php';
$xsltSheet = new DOMDocument;
$xsltSheet->loadXML(ob_get_clean());
$xsltProc = new XSLTProcessor;
$xsltProc->importStyleSheet($xsltSheet);
$dataSet = new DOMDocument;
if(is_file('../dataFiles/xml/' . $dataset . '.xml') && calculator::makedirs('../dataFiles/json/' . $destination . '/' . $frequency)){
//proceed only if the dataset exists and the folders are created correctly
$dataSet->load('../dataFiles/xml/' . $dataset . '.xml');
if(!is_file('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json')){
$filemaker = fopen('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json', 'w');
fclose($filemaker);
}
$xsltProc->transformToURI($dataSet, '../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json');
} else {
throw new Exception('Either dataset does not exist('. $dataset .'), or directories could not be created (dataFiles/json/'. $destination . '/' . $frequency .')');
}
}
public static function populateVarWithXPath($var){
self::$_var[] = $var;
}
public static function makedirs($dirpath, $mode=0777) {
return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}
}
use_calculator.php文件将调用calculate()函数并将三个必需的参数传递给它。然后,在calculate()中,它将执行XML和XSL文件合并
XSL中有关于如何处理XML数据的规则,它所做的是调用connectNodes()函数,该函数将处理新的XML和XSL。这就像是XML/XSL的开端
关键是有一个XML文件列出了处理其他XML数据的内容和方式的所有细节。该文件在calculate()中读取。然后,在计算每段数据时,它以类似于初始阶段的方式调用connectNode()函数
为了让事情更清楚(我希望如此),下面是metricsXmlReader.xsl,它调用connectNodes()
metricsXmlReader.xsl
class calculator{
public static $_var = array();
public function calculate($xml, $xsl, $frequency){
$reader = new DOMDocument;
if(!$reader->load($xsl)) throw new Exception('XSL Could not be loaded: ' . $xsl);
$processor = new XSLTProcessor;
$processor->importStyleSheet($reader);
$processor->registerPHPFunctions();
$processor->setParameter('', 'frequency', $frequency);
$dictionary = new DOMDocument;
if(!$dictionary->load($xml)) throw new Exception('XML Could not be loaded: ' . $xml);
$processor->transformToXML($dictionary);
}
public static function connectNodes($name, $dataset, $processor, $destination, $frequency){
$var = self::$_var;
self::$_var = array();
$test = fopen('blah.txt', 'w');
fclose($test);
ob_start();
require 'templates/' . $processor . '.php';
$xsltSheet = new DOMDocument;
$xsltSheet->loadXML(ob_get_clean());
$xsltProc = new XSLTProcessor;
$xsltProc->importStyleSheet($xsltSheet);
$dataSet = new DOMDocument;
if(is_file('../dataFiles/xml/' . $dataset . '.xml') && calculator::makedirs('../dataFiles/json/' . $destination . '/' . $frequency)){
//proceed only if the dataset exists and the folders are created correctly
$dataSet->load('../dataFiles/xml/' . $dataset . '.xml');
if(!is_file('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json')){
$filemaker = fopen('../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json', 'w');
fclose($filemaker);
}
$xsltProc->transformToURI($dataSet, '../dataFiles/json/' . $destination . '/' . $frequency . '/' . $name . '.json');
} else {
throw new Exception('Either dataset does not exist('. $dataset .'), or directories could not be created (dataFiles/json/'. $destination . '/' . $frequency .')');
}
}
public static function populateVarWithXPath($var){
self::$_var[] = $var;
}
public static function makedirs($dirpath, $mode=0777) {
return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="metrics">
<xsl:for-each select="metric">
<xsl:if test="frequency = $frequency">
<xsl:for-each select="xpath/var">
<xsl:variable name="pusher" select="php:functionString('calculator::populateVarWithXPath', .)" />
</xsl:for-each>
<xsl:variable name="trigger" select="php:functionString('calculator::connectNodes', name, dataset, processor, destination, frequency)" />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我的第一个猜测是,无论PHP试图将文件写入何处,它都不能。您可以尝试为每个人提供权限的绝对路径,如/tmp 此外,您还应该确保能够处理并行请求。因为这是不可伸缩的。如前所述,管道是一种解决方案 惠普
PS:您试过了吗?假设node是作为CLI的不同用户运行的,他们是否具有相同的权限?请尝试生成一个shell,并将php命令作为stdin进行管道传输,通过在dataHi cswl上侦听来检查发生了什么,这听起来不错。你建议我怎么做?您的意思是使用spawn()而不是exec()?关于我的帐户权限的说明。我不是以root用户身份登录(事实上,该帐户的权限较低)。然后我使用这个命令来运行一切:/usr/bin/sudo su-apache-c'',apache拥有root权限。我担心它无法扩展,因为生成新进程的成本很高。但是,这是一个CPU密集型计算,所以Node不应该将工作传递给另一个进程吗?我的意思是,它不会扩展,因为您只能打开blah.txt一次进行写入(至少在没有机制为每个要写入的进程提供始终新的文件夹的情况下)。我真的会从地面开始挖掘,看看你是否能在一个你能写的地方写一个文件,然后确定你的文件应该打开的地方。