указатели — Как передать процесс PHP с помощью функции proc_open ()?

В этом случае есть два файла PHP, stdin.php (дочерний компонент процесса) и proc_open.php (родительский компонент процесса), оба хранятся в одной папке public_html домена. Существует также Программа X, который передает данные в stdin.php.


stdin.php (этот компонент работает)

Это процесс, который не должен выполняться через браузер, поскольку он предназначен для получения входных данных из Программы X и резервного копирования всего этого в файл (с именем stdin_backup). Этот процесс работает, потому что каждый раз, когда программа X передает данные, процесс полностью их резервирует. Если этот процесс выполняется с незавершенным вводом (как в случае его выполнения из браузера), процесс создает файл (с именем stdin_error) с текстом «ОШИБКА».

Ниже часть кода опущена, потому что процесс работает (как упомянуто выше). Показанный код просто для иллюстрации:

#!/usr/bin/php -q
<?php
// Get the input
$fh_stdin = fopen('php://stdin', 'rb');

if (is_resource($fh_stdin)) {
// ... Code that backs up STDIN in a file ...
} else {
// ... Code that logs "ERROR" in a file ...
}
?>

proc_open.php (этот компонент не работает)

Это процесс, который должен выполняться через браузер и предназначен для передачи ввода в stdin.php, как это делает программа X. Этот процесс терпит неудачу, потому что каждый раз, когда он выполняется, нет никакого сигнала о выполнении stdin.php: нет файла stdin_error, нет файла stdin_backup, даже файла PHP error_log.

Код:

// Execute a PHP process and pipe input to it
//  - Specify process command
$process_path = __DIR__ . '/stdin.php';
$process_execution_command = 'php ' . $process_path;

//  - Specify process descriptor
$process_descriptor = array(
0 => array('pipe', 'r') // To child's STDIN
);

//  - Specify pipes container
$pipes = [];

//  - Open process
$process = proc_open($process_execution_command, $process_descriptor, $pipes);

if (is_resource($process)) {
//  - Send data to the process STDIN
$process_STDIN = 'Data to be received by the process STDIN';
fwrite($pipes[0], $process_STDIN);
fclose($pipes[0]);

//  - Close process
$process_termination_status = proc_close($process);
}

Я не уверен, что команда передана proc_open() правильно, потому что я не нашел примеров для этого случая, и, как упоминалось выше, этот скрипт не работает. Я не знаю, что еще может быть неверным с proc_open.php.

Кроме того, когда я выполняю процесс proc_open.php, бесконечный цикл создает, печатая следующую строку снова и снова:

X-Powered-By: PHP / 5.5.20 Тип содержимого: text / html; кодировка = UTF-8


судимое popen('php ' . __DIR__ . '/stdin.php', 'w') вместо этого и имел точно такой же результат: ошибка бесконечного цикла при печати той же строки, что и выше, без ошибок, без журналов и без сигналов выполнения stdin.php.

0

Решение

Если я правильно понимаю ваш вопрос, вы хотите открыть процесс и записать данные в поток STDIN этого процесса. Вы можете использовать proc_open функция для этого:

$descriptors = array(
0 => array("pipe", "r"),  // STDIN
1 => array("pipe", "w"),  // STDOUT
2 => array("pipe", "w")   // STDERR
);

$proc = proc_open("php script2.php", $descriptors, $pipes);
fwrite($pipes[0], "Your data here...");
fclose($pipes[0]);

$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);

fclose($pipes[1]);
fclose($pipes[2]);

$exitCode = proc_close($proc);

Если вы просто хотите тестовое задание Ваш второй сценарий, вероятно, было бы проще просто использовать команду оболочки:

$ echo "your data" | php script2.php

Или, в качестве альтернативы,

$ php script2.php < datafile.txt

Обновление, учёт вашего правки на вопрос

При использовании POPEN Функция, вы можете открыть процесс для чтения или записи. Это позволяет вам читать поток STDOUT процесса или записывать в поток STDIN (но не оба одновременно; если это требование, вам нужно использовать proc_open). Если вы хотите записать в поток STDIN, укажите "w" как 2-й параметр popen чтобы открыть процесс записи:

$fh_pipe = popen(
'php script1.php',
'w'   // <- "w", not "r"!
);

fwrite($fh_pipe, 'EMAIL TEXT') ;
pclose($fh_pipe);
3

Другие решения

Других решений пока нет …