В этом случае есть два файла 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.
Если я правильно понимаю ваш вопрос, вы хотите открыть процесс и записать данные в поток 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);
Других решений пока нет …