У меня есть приложение, в основном написанное на PHP, но есть пакет npm с функциями, которые мне нужно включить в мое приложение. Я должен передаю строку HTML в приложение Node.js, но у меня возникают проблемы с корректностью. Я использую:
exec('node '.$rootPath.'node/app.js '.$imageId.' email '.escapeshellcmd($emailString).' 2>&1', $output, $retVar);
для отправки данных в мое приложение Node.js, но я не уверен, как их декодировать, когда они попадут туда и должны быть обработаны через JavaScript. Есть ли способ убрать escapeshellcmd() в JavaScript? Или есть другой способ передать эти длинные строки HTML через командную строку?
Обновлено: Вот точный метод, который я использую для передачи моей информации в Node.js:
try{
$emailString = escapeshellcmd($decoded);
//`node $rootPath'node/app.js' $imageId email $emailString 2>&1`;
exec('node '.$rootPath.'node/app.js '.$imageId.' email "'.$emailString.'" 2>&1', $output, $retVar);
print_r($output);
}catch(Exception $e){
echo $e->getMessage()."\n";
}
А вот app.js:
process.argv.forEach(function(value, index, array){
if (index == 2){
id = value;
}
if (index == 3){
type = value;
}
if (index == 4){
visual = value;
}
});
console.info('******* FROM NODE********');
console.info(visual);
Кажется, что только первая строка передается или собирается и печатается обратно, и похоже, что она все еще закодирована (если только консоль не перекодирует при печати). Также я не уверен, почему кажется, что значения добавляются, а не перезаписываются:
Array
(
[0] => ******* FROM NODE********
\<head\>\<style type=text/css\>body \{padding:0\; margin:0\; text-align:center\;.tbl1 \{background-color:\#a53f0f\; color:\#fff\; text-align:center\; font-size:\<body data-gramm=true data-gramm_editor=true data-gramm_id=ccdbd45c-b0bf-4691-9\<table border=0 cellpadding=0 cellspacing=0 style=background-color:
)
Array
(
[0] => ******* FROM NODE********
\<head\>\<style type=text/css\>body \{padding:0\; margin:0\; text-align:center\;.tbl1 \{background-color:\#a53f0f\; color:\#fff\; text-align:center\; font-size:\<body data-gramm=true data-gramm_editor=true data-gramm_id=ccdbd45c-b0bf-4691-9\<table border=0 cellpadding=0 cellspacing=0 style=background-color:
[2] => ******* FROM NODE********
\<html xmlns=http://www.w3.org/1999/xhtml xmlns:v=urn:schemas-microsoft-com:vml \<meta name=viewport content=width=device-width,e\>
)
@ srimaln91 srimaln91 Он не отбрасывается, а stderr перенаправляется на stdout - тот же результат, что и в терминале. Сбросить будет 2>/dev/null
@ srimaln91 Однако я предпочитаю обрабатывать все стандартные потоки отдельно, используя proc_open.
@Quasimodo'sclone Пожалуйста, смотрите правку.
Сначала +1 голос за минимальный воспроизводимый пример. Другой вопрос, независимо от проблемы: вам действительно нужно передавать тело письма аргументом, который может стать очень большим текстом? Обычный способ обработки текстовых данных — действовать как фильтр между потоками STDIN и STDOUT.






Примечание. Вы должны использовать потоки вместо аргументов для обработки данных. Это обычный способ работы команд в мире Unix.
В своем коде вы пытаетесь использовать escapeshellcmd, чтобы избежать двойной кавычки " инкапсулированной строки аргумента. Это не работает. Также есть функция escapeshellarg PHP. Он будет заключать строку в одинарные кавычки ' и escape-символы, которые даже в строках с одинарными кавычками обрабатываются оболочкой особым образом.
Предполагая, что $decoded что-то вроде
$decoded = '<body lang = "en">very boring message</body>';
то вы сами его в кавычки не заключаете. Пусть escapeshellarg сделает свое дело.
$emailString = escapeshellarg($decoded);
$imageIdString = escapeshellarg($imageId);
exec("node app.js {$imageIdString} email {$emailString} 2>&1", $output, $retVar);
Как упоминалось выше, вам действительно следует рассмотреть возможность работы с потоками вместо аргументов. Преимущество в том, что данные могут расти до произвольного размера. Кроме того, proc_open обрабатывает STDOUT и STDERR отдельно. Это можно сделать так:
try
{
if ($handle = proc_open("node app.js {$imageId} email";, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $streams))
{
[$stdin, $stdout, $stderr] = $streams;
fwrite($stdin, $decoded);
fclose($stdin);
$output = stream_get_contents($stdout);
fclose($stdout);
$error = stream_get_contents($stderr);
fclose($stderr);
proc_close($handle);
}
echo 'OUTPUT:', PHP_EOL, $output, PHP_EOL;
echo 'ERRORS:', PHP_EOL, $error, PHP_EOL;
}
catch(Exception $e)
{
echo $e->getMessage(), PHP_EOL;
}
Вот пример скрипта node.js, обрабатывающего как данные по аргументу, так и по стандартному вводу:
(() =>
{
'use strict';
console.info('******* FROM NODE********');
const
getStdin = require('get-stdin');
var id, type, visual;
[,, id, type, visual] = process.argv;
// if 4th command line argument is present, use that
if (undefined !== visual)
processData(visual);
// otherwise read data from stdin stream
else
getStdin().then(visual =>
{
processData(visual);
});
function processData(data)
{
console.info('id' , id );
console.info('type', type);
console.info('STDIN:', data);
console.error('no errors');
console.info('******* DONE *******');
}
})();
Хотя ответ клона Квазимодо действительно работает, его комментарий к вопросу заставил меня задуматься о передаче больших строк HTML. Вместо этого я решил записать html в файл и указать идентификатор.
Почему вы используете
2>&1. Не нужно отказываться от вывода.