Я попытался вывести простую команду ping на веб-странице аналогичным образом (и одновременно), поскольку она отображается в терминале, используя shell_exec; Но он отображается только после полного выполнения, в то время как мне нужно было его отображать всякий раз, когда он отображается на терминале,
Мой код
<?php $i= shell_exec("ping -c 4 google.com"); echo "<pre> $i <pre>"; ?>
Он ждет некоторое время и сбрасывает все это на одном снимке. Может ли PHP распознать вывод каждой строки и отобразить ее на веб-странице
РЕДАКТИРОВАТЬ
Я тоже пробовал это
<?php $proc = popen("ping -c 4 google.com", 'r'); echo '<pre>'; while (!feof($proc)) { echo fread($proc, 4096); } echo '</pre>'; ?>
Но все же я получаю тот же результат ..
РЕДАКТИРОВАТЬ
Когда я пытался выполнить этот PHP-код в терминале, (php test.php), он работает правильно так же, как он дает, когда мы непосредственно выполняем ping на сервере. но на веб-странице все равно.
Ух, странное поведение из веб-браузера. Я использую этот код:
<?php ob_end_flush(); ini_set("output_buffering", "0"); ob_implicit_flush(true); function pingtest() { $proc = popen("ping -c 5 google.com", 'r'); while (!feof($proc)) { echo "[".date("i:s")."] ".fread($proc, 4096); } } ?> <!DOCTYPE html> <html> <body> <pre> Immediate output: <?php pingtest(); ?> </pre> </body> </html>
В браузере содержимое появляется после того, как все байты были получены. Но контент на самом деле доставлен вовремя, выполните этот тест:
wget -O - -q "http://localhost/ping.php"
Вы увидите, что ответ доставляется php & apache2 вовремя.
Я использую этот вид выполнения на длительной задаче некоторое время, но используя более сложное решение:
interface (test.html)
<!DOCTYPE html> <html> <head> <title>Simple EventSource example</title> </head> <body> <script type="text/javascript"> function eventsourcetest() { var ta = document.getElementById('output'); var source = new EventSource('test.php'); source.addEventListener('message', function(e) { if (e.data !== '') { ta.value += e.data + '\n'; } }, false); source.addEventListener('error', function(e) { source.close(); }, false); } </script> <p>Output:<br/><textarea id="output" style="width: 80%; height: 25em;"></textarea></p> <p><button type="button" onclick="eventsourcetest();">ping google.com</button> </html>
Компонент боковой стороны сервера (test.php)
<?php ob_end_flush(); ini_set("output_buffering", "0"); ob_implicit_flush(true); header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); function echoEvent($datatext) { echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n"; } echoEvent("Start!"); $proc = popen("ping -c 5 google.com", 'r'); while (!feof($proc)) { echoEvent(fread($proc, 4096)); } echoEvent("Finish!");
Поместите оба файла в одном месте на веб-сервере и введите test.html, я думаю, что это то, что вы ищете с самого начала.
Используйте буферизацию вывода и flush
. Вы также можете посмотреть в компонент процесса Symfony 2.
Это не вопрос PHP, а скорее его общий вопрос между php и браузером.
В PHP: убедитесь, что буферизация вывода выключена, вы можете сделать это, запустив ob_end_clean()
перед выводом чего-либо.
Поскольку эта публикация SO предполагает, что вам нужно либо поместить первую строку, выведенную на 512 байт, либо указать кодировку кодировки через HTTP-заголовок. Решение прокладки может быть самым простым способом, в основном это: echo(str_pad("Live Ping Test!",512));
и затем начните повторять результат вашего fread
.
Вы можете попробовать использовать flush (), чтобы очистить вывод как и когда он готов, и использовать passthru () для выполнения команды.
Карлос С Сото прав, вы должны использовать javascript. EventSource – это путь. В принципе, это код javascript, который будет постоянно вызывать URL-адрес
Вы можете написать вывод ping в файле и написать скрипт php, который будет читать последнюю строку, а затем вызвать этот скрипт с eventource.
Поиск «События, отправленные сервером» в Интернете, чтобы найти больше примеров
если может разрешить использование пользователя apache. если ваш пользователь root отличается и пользователь сервера отличается, то он не позволит выполнить команду командной строки.
Я испытал ответ Карлоса на моей стороне …
и я ДОЛЖЕН добавить flush (); ob_flush (); для того, чтобы он работал должным образом (оба требовали флеша и ob_flush)
как это
<?php $proc = popen("ping -c 5 google.com", 'r'); while (!feof($proc)) { echo "[".date("i:s")."] ".fread($proc, 4096).'<br>';flush();ob_flush(); } ?>