Вы можете использовать proc_open
для подачи входных данных и получения выходных данных процесса через каналы. Тем не менее, не похоже, что меньше учитывает взаимодействие с пользователем по каналам, поскольку оно в основном ухудшается до команды cat
. Вот мой первый (неудачный) подход:
<?php
$dspec = array(
0 = array('pipe', 'r'), // pipe to child process's stdin
1 = array('pipe', 'w'), // pipe from child process's stdout
2 = array('file', 'error_log', 'a'), // stderr dumped to file
);
// run the external command
$proc = proc_open('less name_of_file_here', $dspec, $pipes, null, null);
if (is_resource($proc)) {
while (($cmd = readline('')) != 'q') {
// if the external command expects input, it will get it from us here
fwrite($pipes[0], $cmd);
fflush($pipes[0]);
// we can get the response from the external command here
echo fread($pipes[1], 1024);
}
fclose($pipes[0]);
fclose($pipes[1]);
echo proc_close($proc);
Я полагаю, что для некоторых команд этот подход может сработать - и в справочной странице php есть несколько примеров для proc_open
, которые могут быть полезны для просмотра - но для less
вы получите весь файл обратно и никакой возможности для взаимодействия, возможно, по причинам, указанным в ответе Viper_Sb.
... Но, кажется, достаточно просто смоделировать less
, если это все, что вам нужно. Например, вы можете прочитать выходные данные команды в массив строк и передать их кусками размером в укус:
<?php
$pid = popen('cat name_of_file_here', 'r');
$buf = array();
while ($s = fgets($pid, 1024))
$buf[] = $s;
pclose($pid);
for ($i = 0; $i < count($buf)/25 && readline('more') != 'q'; $i++) {
for ($j = 0; $j < 25; $j++) {
echo array_shift($buf);
}
}