I’m trying to execute a node.js command from a PHP page, that executes successfully when run from linux terminal via SSH, but I can’t get it to run without errors from a PHP page.
The environment is a Apache CentOS VPS hosting account.
I’m more familiar with PHP than node.js. The node.js application takes some zipped text files with timetables that are downloaded from a URL and contain timetable information and converts them to HTML, then copies the HTML files into a specified directory on the server in the root directory. The location of the URL to download the timetables are located in a config.json file that is loaded aysnchronously. When trying to run it from a PHP page, I’m using this function to display the output while testing it:
function liveExecuteCommand($cmd) {
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');
$live_output = ""; $complete_output = "";
while (!feof($proc)) {
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "$live_output<br />";
@ flush();
}
pclose($proc);
// get exit status
preg_match('/[0-9]+$/', $complete_output, $matches);
// return exit status and intended output
return array (
'exit_status' => intval($matches[0]),
'output' => str_replace("Exit status : " . $matches[0], '', $complete_output)
);
}
Then, to see the result on the PHP page, I use this:
$result = liveExecuteCommand($command);
if($result['exit_status'] === 0){
echo "the command succeeded";
} else {
echo "the command did not succeed";
}
This function works and allows me to see the output, which always contains notifications of javascript syntax errors when run from the page, but not from command line. I can’t seem to get the node.js application to run without syntax errrors from the PHP page. I have tried several things:
1. Running just a node command from the PHP page that this node.js application will accept along with a ‘config’ file parameter that specifies a config file that downloads the data to be converted into HTML (asynchronously)
$command = 'export PATH=$PATH:~/bin; the-node-command --configPath ~/public_html/website.com/gtfs-to-html-configs/config.json';
and here’s the error I’m getting:
//get configuration file necessary for node.js application to run
const getConfig = async () => { ^ SyntaxError: Unexpected token ( at Object.exports.runInThisContext (vm.js:53:16)
2. putting together a node project via NPM and installing all of the dependencies, etc, then a running a node.js file within that package that accomplishes the same thing:
$command = 'export PATH=$PATH:~/transit-app; app.js';
and here’s the error I’m getting:
//it's happening at the 'require' line at beginning of the app.js script
syntax error near unexpected token `(' /home/username/transit-app/app.js:line 1: `const gtfsToHTML = require('gtfs-to-html');'
3. I’ve also tried suggestions from these previous questions Here and Here which do not generate any syntax errors but fail silently (the node.js program is not run and no HTML tables are created).
I’ve also confirmed that the user that runs the PHP script and the node.js command are the same (or at least tried to verify it using PHP’s
get_current_user();
Ideally I just want to run the node.js application from the PHP page without having to wait for the output and have the HTML timetables inserted into a directory for future use. The PHP page doesn’t even use the timetables. That’s all possible while running the node.js application directly from the command line, but not from a PHP page.
Update #1
The file that contains gtfs-to-html node.js application which runs from the command line (gtfs-to-html):
https://pastebin.com/dHecqmf8
The json config file that gtfs-to-html needs to make the HTML timetables:
https://pastebin.com/4a4MKuPd
The php page that I’m trying to run the node.js command from:
https://pastebin.com/5JczB76T
The gtfs-to-html command is found and the application is run, so I know it’s in the directory I specified, but still getting this syntax error in the node.js application file when trying to run the command from the php page:
Array
(
[exit_status] => 1
[output] => /home/mcedd/lib/node_modules/gtfs-to-html/bin/gtfs-to-html.js:39
const getConfig = async () => {
^
SyntaxError: Unexpected token (
at Object.exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:513:28)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.runMain (module.js:575:10)
at run (node.js:348:7)
at startup (node.js:140:9)
at node.js:463:3
)
3
Answers
The require might not find the package in the path since it is actually executed from the PHP file location I think that you will need to add the path also to the node modules relative to where the PHP is executed.
But since it said syntax error I would need to see the full file.
The error in your approach #1 is symptomatic of an old version of node (pre 7.6) that doesn’t recognize the ‘async’ keyword. Try adding:
to the-node-command to double check this. If it is, in fact an old version of node, update it.
With approach #2, you are trying to run app.js as a shell script. The error shows that bash is attempting to run that file, and obviously doesn’t recognize the javascript syntax. You should instead be using:
Once you have either of these two approaches working, you should indeed be able to achieve your ideal case by following the answer here: php exec command (or similar) to not wait for result
From cases like this you need to install node php
the code: