How can I pass parameters when calling a Node.js script from PHP exec()?
Asked Answered
C

2

11

I'm trying to implement iOS push notifications. My PHP version stopped working and I haven't been able to get it working again. However, I have a node.js script that works perfectly, using Apple's new Auth Key. I am able to call that from PHP using:

chdir("../apns");
exec("node app.js &", $output);

However, I would like to be able to pass the deviceToken and message to it. Is there any way to pass parameters to the script?

Here's the script I'm trying to run (app.js):

var apn = require('apn');

var apnProvider = new apn.Provider({  
     token: {
        key: 'apns.p8', // Path to the key p8 file
        keyId: '<my key id>', // The Key ID of the p8 file (available at https://developer.apple.com/account/ios/certificate/key)
        teamId: '<my team id>', // The Team ID of your Apple Developer Account (available at https://developer.apple.com/account/#/membership/)
    },
    production: false // Set to true if sending a notification to a production iOS app
});

var deviceToken = '<my device token>';
var notification = new apn.Notification();
notification.topic = '<my app>';
notification.expiry = Math.floor(Date.now() / 1000) + 3600;
notification.badge = 3;
notification.sound = 'ping.aiff';
notification.alert = 'This is a test notification \u270C';
notification.payload = {id: 123};

apnProvider.send(notification, deviceToken).then(function(result) {  
    console.log(result);
    process.exit(0)
});
Concave answered 6/5, 2017 at 21:1 Comment(0)
W
21

You can pass parameters as you would pass it to any other script.

node index.js param1 param2 paramN

You can access the arguments through process.argv

The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched. The first element will be process.execPath. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command line arguments.

exec("node app.js --token=my-token --mesage=\"my message\" &", $output);

app.js

console.log(process.argv);

/* 
Output:

[ '/usr/local/bin/node',
  '/your/path/app.js',
  '--token=my-token',
  '--mesage=my message' ] 
*/

You can use minimist to parse the arguments for you:

const argv = require('minimist')(process.argv.slice(2));
console.log(argv);

/*
 Output

{
    _: [],
    token: 'my-token',
    mesage: 'my message'
} 
*/

console.log(argv.token) //my-token
console.log(argv.message) //my-message
Works answered 6/5, 2017 at 21:4 Comment(0)
V
0

After a lot of work, I have a solution. I am using a local web UI to send and receive data to/from Arduino using AJAX, the php script is:

<?php
/**
* It is already not necessary to go to Device Manager> Ports (COM & LPT)>Arduino XXX (COMXX)>right, NO, the script PruebaCOMRetrieve.bat detect the COM port Arduino is connected to. 
* click>Properties>
* Port Settings>Advanced>uncheck "use FIFO buffers ........."
* In other hand, remeber that the Tx speed has to be the same in writeandread.js as in
* Arduino sketch and in the COM
* properties in Device manager, I selected 115200 b/s.
*
*/
$t = $_POST['text1'];
include 'PruebaBatchCOM.php';
$puerto = escapeshellarg($usbCOM);
$dato = escapeshellarg($t);
exec("node C:\\xampp\\htdocs\\DisenoWEBTerminados\\BatteryTesterFinal\\Scripts\\writeandread.js 
{$puerto} {$dato} 2>&1", $output1);
$str = implode($output1);
$str1 = explode(",",$str);
$myJSON = json_encode($str1);
echo $myJSON;
?>

PruebaBatchCOM.php

<?php
$puerto = array(); 
$file111 = "PruebaCOMRetrieve.bat";
exec($file111, $puerto);
$usbCOM = implode(",",$puerto); 
?>

PruebaCOMRetrieve.bat

@echo off
setlocal

for /f "tokens=1* delims==" %%I in ('wmic path win32_pnpentity get caption  
/format:list ^| find "Arduino Uno"') do (
call :setCOM "%%~J"
)

:: end main batch
goto :EOF

:setCOM <WMIC_output_line>
:: sets _COM#=line
setlocal
set "str=%~1"
set "num=%str:*(COM=%"
set "num=%num:)=%"
set port=COM%num%
echo %port%

The Node Js script is:

//writeandread.js
var portName = process.argv[2];
var dato = process.argv[3];

var SerialPort = require("serialport");
var Readline = require('@serialport/parser-readline');
var serialport = new SerialPort(portName, { baudRate: 115200 });
   // Look for return and newline at the end of each data packet
var parser = serialport.pipe(new Readline({ delimiter: '\n' }));

serialport.on('open', function(err) {
// A timeout is necessary to wait the port to open (if not working, try to 
increase the milliseconds value)
setTimeout(function() {
    serialport.write(dato);
}, 1700);
if(err) {
   console.log('Error when trying to open:' + err);
}
parser.on('data', function(data) {
    console.log(data);
    serialport.close(function (err) {
    if(err){
     console.log('port closed', err);
    }
   });
  });
 });

serialport.on('close', () => {
 console.log('Bye');
});

With this scripts one can send and receive data from Arduino and pass it to AJAX script in the client side and do what one wants. Now I am adding a script to php firt one to detect programmatically the COM port Arduino is connected to.

enjoy.

Vacla answered 29/10, 2020 at 14:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.