Передача HTML в Node.js из PHP

У меня есть приложение, в основном написанное на 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\>
)

Почему вы используете 2>&1. Не нужно отказываться от вывода.

srimaln91 19.03.2019 03:59

@ srimaln91 srimaln91 Он не отбрасывается, а stderr перенаправляется на stdout - тот же результат, что и в терминале. Сбросить будет 2>/dev/null

Quasimodo's clone 19.03.2019 04:00

@ srimaln91 Однако я предпочитаю обрабатывать все стандартные потоки отдельно, используя proc_open.

Quasimodo's clone 19.03.2019 04:05

@Quasimodo'sclone Пожалуйста, смотрите правку.

chaoskreator 20.03.2019 03:18

Сначала +1 голос за минимальный воспроизводимый пример. Другой вопрос, независимо от проблемы: вам действительно нужно передавать тело письма аргументом, который может стать очень большим текстом? Обычный способ обработки текстовых данных — действовать как фильтр между потоками STDIN и STDOUT.

Quasimodo's clone 20.03.2019 05:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
5
150
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Примечание. Вы должны использовать потоки вместо аргументов для обработки данных. Это обычный способ работы команд в мире 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 в файл и указать идентификатор.

Другие вопросы по теме