在这种情况下,有两个PHP文件, stdin.php (子进程组件)和 proc_open.php (父进程组件),两者都存储在同一个文件中域的public_html的文件夹。还有程序X ,它将数据传输到stdin.php。
stdin.php (此组件有效)
这是一个不应该通过浏览器执行的进程,因为它的目的是接收来自程序X的输入,并将其全部备份到一个文件(名为stdin_backup)中。 此过程正在运行,因为每次程序X管道输入时,该过程都会完全备份。如果在未传递输入的情况下执行此过程(例如从浏览器执行此操作),则该过程将创建一个文件(名为stdin_error),其中包含文本" 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 (此组件无效)
这是一个必须通过浏览器执行的进程,并且正如程序X所做的那样,目的是将输入传递给stdin.php。此过程失败,因为每次执行时都没有执行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 :(得分:3)
如果我理解你的问题,你想打开一个进程并将数据写入该进程的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);
如果您只是想测试第二个脚本,那么简单地使用shell命令可能会更容易:
$ echo "your data" | php script2.php
或者,
$ php script2.php < datafile.txt
更新,记录您对问题的修改
使用popen功能时,您可以打开读取或写入过程。这允许您读取进程'STDOUT流或写入STDIN流(但不是两者;如果这是一个要求,则需要使用proc_open
)。如果要写入STDIN流,请将"w"
指定为popen
的第二个参数以打开写入过程:
$fh_pipe = popen(
'php script1.php',
'w' // <- "w", not "r"!
);
fwrite($fh_pipe, 'EMAIL TEXT') ;
pclose($fh_pipe);