Как отображать процент загрузки и как это сделать без javascript?
Я хочу сделать что-то похожее на загрузчиков в PHP, поэтому я использовал этот код:
<?php $x=1; while($x<=100) { echo "Loading: $x %<br>"; $x++; } ?>
Чтобы он отображался с «Загрузка 1%» на «Загрузка 100%». Но это приведет к появлению всех по одному, не исчезая после появления новой строки. Поэтому я хочу знать, как сделать новую строку, и старые исчезнут, и это начинается после загрузки страницы, поэтому пользователь сможет наблюдать загрузку загрузчика с 1% до 100%.
ОБНОВЛЕНИЕ: Я знаю, что я должен использовать JS и / или Ajax для его достижения, я просто хотел знать, есть ли способ сделать это и в PHP 🙂
21 Solutions collect form web for “Как отображать процент загрузки и как это сделать без javascript?”
Для выполнения долговременных задач распространено, но не очень просто реализовать в первый раз. Вот полный пример.
(образец долговременной задачи в продукте Sellermania )
контекст
Задание
Представьте, что у вас есть следующая задача, и вы хотите отобразить индикатор выполнения для ваших посетителей.
PHP task.php
<?php $total_stuffs = 200; $current_stuff = 0; while ($current_stuff < $total_stuffs) { $progress = round($current_stuff * 100 / $total_stuffs, 2); // ... some stuff sleep(1); $current_stuff++; }
Пользовательский интерфейс
Ваш красивый пользовательский интерфейс выглядит так:
HTML ui.html
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>My Task!</title> </head> <body> <a id="run_task" href="#">Run task</a> <div id="task_progress">Progression: <span id="task_progress_pct">XX</span>% <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript"> $('#run_task').click(function(e) { e.preventDefault(); $.get('task-launch.php'); }); </script> </body> </html>
Пусковая установка
Нам нужно запустить задачу в фоновом режиме, чтобы сделать эту демонстрацию актуальной. Таким образом, этот php-скрипт будет вызываться асинхронно при нажатии «run» и будет выполнять задачу выше в фоновом режиме.
PHP task-launch.php
<?php // launches the task in background // see https://stackoverflow.com/a/12341511/731138 for details about the arguments exec("/usr/bin/php task.php > /dev/null 2>&1 &");
Проблемы
Здесь есть три проблемы:
-
вы можете запустить задачу несколько раз, нажав несколько раз кнопку запуска, как избежать нескольких задач в фоновом режиме в одно и то же время?
-
задача выполняется на стороне сервера, поэтому нам нужно что-то сделать для доступа к серверу и запросить информацию о прогрессировании.
-
и когда мы будем подключены к серверной стороне, переменная
$progress
недоступна для чтения, потому что она сохраняется в контекстеtask.php
запускаtask.php
.
Решения
Храните информацию о прогрессировании в нечто, читаемое снаружи
Как правило, информация о прогрессировании хранится в базе данных или в файле или в любом месте, которое может быть записано программой (ваша задача actaully), и читается другой (ваш ui, где должна отображаться прогрессия).
Я разработал класс для обмена данными в нескольких php-приложениях ( доступно здесь в github ), он работает примерно так же, как и stdClass
но всегда безопасно синхронизирует его содержимое в файл.
Просто скачайте src/Sync.php
и измените task.php выше:
PHP task.php
<?php require("Sync.php"); $total_stuffs = 200; $current_stuff = 0; $shared = new Sync("some_file.txt"); $shared->progress = 0; while ($current_stuff < $total_stuffs) { $shared->progress = round($current_stuff * 100 / $total_stuffs, 2); // ... some stuff sleep(1); $current_stuff++; } // to tell the follower that the task ended $shared->progress = null;
Важное примечание : здесь some_file.txt
– это где хранятся общие данные вашей задачи, поэтому не стесняйтесь использовать «task_ [user_id] .txt», например, если каждый пользователь имеет свою собственную задачу. И посмотрите на readme github для оптимизации доступа к файлам.
Используйте синхронизированную переменную для защиты запуска задачи
- Прогрессия устанавливается в 0 в начале задачи, поэтому прежде всего нужно проверить перед запуском задачи, что эта прогрессия не установлена на 0.
PHP task-launch.php
<?php require("Sync.php"); $shared = new Sync("some_file.txt"); if (is_null($shared->progress)) { exec("/usr/bin/php task.php > /dev/null 2>&1 &"); }
- Если кнопку запуска дважды щелкнуть дважды, у нас все еще может быть 2 экземпляра задачи. Чтобы справиться с этим случаем, нам нужно имитировать мьютекс, одним словом, сделать переменную доступной только для текущего приложения, чтобы сделать некоторые вещи – другие приложения будут спать до тех пор, пока разделяемая переменная не будет разблокирована.
PHP task.php
<?php require("Sync.php"); $total_stuffs = 200; $current_stuff = 0; $shared = new Sync("some_file.txt"); // here is the magic: impossible to set the progression to 0 if an instance is running // ------------------ $shared->lock(); if (!is_null($shared->progress)) { $shared->unlock(); exit ; } $shared->progress = 0; $shared->unlock(); // ------------------ while ($current_stuff < $total_stuffs) { $shared->progress = round($current_stuff * 100 / $total_stuffs, 2); // ... some stuff sleep(1); $current_stuff++; } // the task ended, no more progression $shared->progress = null;
Предупреждение : если ваша задача выйдет из строя и никогда не дойдет до конца, вы больше не сможете ее запускать. Чтобы избежать таких случаев, вы также можете сохранить getmypid()
и некоторое time()
в вашей общей переменной и добавить логику тайм-аута в свою задачу.
Используйте опрос, чтобы спросить информацию о продвижении сервера
Опрос означает, что каждый промежуток времени запрашивает информацию о прогрессировании (например, 1 с, 5 секунд или что-то еще). Одним словом, клиент запрашивает информацию о прогрессии на сервере каждые N секунд.
- на стороне сервера нам нужно закодировать обработчик для ответа на информацию о прогрессировании.
PHP task-follow.php
<?php require("Sync.php"); $shared = new Sync("some_file.txt"); if ($shared->progress !== null) { echo $shared->progress; } else { echo "--"; // invalid value that will break polling }
} else {<?php require("Sync.php"); $shared = new Sync("some_file.txt"); if ($shared->progress !== null) { echo $shared->progress; } else { echo "--"; // invalid value that will break polling }
- на стороне клиента нам нужно закодировать бизнес-запрос «Запросить информацию о развитии на сервер»
HTML ui-polling.html
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>My Task!</title> </head> <body> <a id="run_task" href="#">Run task</a> <div id="task_progress">Progression: <span id="task_progress_pct">XX</span>% <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript"> $('#run_task').click(function(e) { e.preventDefault(); <!-- not a good practice to run a long-running task this way but that's a sample --> $.get('task-launch.php'); <!-- launches the polling business --> setTimeout(function() { getProgressionInformation(); }, 1000); }); function getProgressionInformation() { $.get('task-follow.php', function(progress) { $('#task_progress_pct').html(progress); if (progress !== '--') { <!-- if the task has not finished, we restart the request after a 1000ms delay --> setTimeout(function() { getProgressionInformation(); }, 1000); } }); } /* the task might be already running when the page loads */ $(document).ready(function() { getProgressionInformation(); }); </script> </body> </html>
С минимальным JavaScript?
Я также разработал плагин jquery, domajax , предназначенный для выполнения «ajax без javascript» (фактически, сам плагин находится в jQuery, но при использовании его не требуется код JavaScript), и путем объединения параметров вы можете делать опросы.
В нашей демонстрации:
- последователь становится:
PHP task-follow.php
<?php require("Sync.php"); $shared = new Sync("some_file.txt"); if ($shared->progress !== null) { echo $shared->progress; }
- источник пользовательского интерфейса становится:
HTML ui-domajax.html
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>My Task!</title> </head> <body> <a href="#" id="run-task" class="domajax click" data-endpoint="task-launch.php" data-domajax-complete="#polling" >Run task</a> <div id="polling" data-endpoint="task-follow.php" data-delay="1000" data-output-not-empty="#task-progress-pct" data-domajax-not-empty="" ></div> <div id="task-progress">Progression: <span id="task-progress-pct">--</span>% <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="//domajax.com/js/domajax/jquery.domajax.js"></script> </body> </html>
Как вы можете видеть, в этом коде нет видимого javascript. Чистота не так ли?
Другие примеры доступны на веб-сайте domajax , посмотрите вкладку «Управлять индикаторами прогресса легко» в демонстрационной панели. Все параметры документально задокументированы.
PHP – это серверный язык, и он дает вам ответ на основе запроса.
вы не можете манипулировать (как хотите) на DOM .
для этого вы должны использовать javascript и AJAX для изменения элементов DOM на основе результата PHP
Для этого вам не нужен Javascript. Если задача, которую вы ожидаете, является постоянной, вы можете просто создать скрипт PHP, который:
- Находит задачу (например, в БД)
- Проверяет процент завершения задачи
- Echo – это процент для пользователя
- Если процент <100%
- Обновить страницу
- В противном случае перенаправление на полную страницу.
Вы можете обновить не-javascript, используя мета-обновление HTML. Это может выглядеть примерно так (не делайте PHP примерно через 10 лет, поэтому рассматривайте это как псевдокод):
<?php $taskId = $_GET("taskId"); $task = lookupTask($taskId); $refresh = $task->percentComplete < 100; ?> <html> <head> <? if($refresh): ?> <meta http-equiv="refresh" content="5"> <? else: ?> <meta http-equiv="refresh" content="0; url=taskComplete?taskId=<?=$taskId ?>" /> <? endif; ?> </head> <body> Loading: <?=$task->percentComplete ?> </body> </html>
Другим подходом, действительно уродливым взломом , было бы использование метода flush () PHP. Flush заставит текущий выходной буфер работать с PHP (например, CGI). Этот вывод иногда будет буферизироваться хост-приложением, но на некоторых веб-серверах он будет отправлять результат прямо пользователю. Подробнее здесь: http://php.net/manual/en/function.flush.php
Возможно, вам придется объединить его с ob_flush, но я не уверен: http://php.net/manual/en/function.ob-flush.php
С помощью CSS вы можете скрыть весь текст «погрузки» по умолчанию, но переопределите это значение для загружаемого текста последнего ребенка и покажите его. Например:
<style type="text/css"> .loadText { display: none; } .loadText:last-child { display: block; } </style> <?php for ($x = 0; $x <= 100; $x++) { echo '<div class="loadText">Loading: ', $x, '%</div>'; flush(); } ?>
Оба этих решения ужасны, я просто хотел поделиться ими для полноты 🙂
Выяснить здесь немного ответов;
PHP – это серверный язык, но это не значит, что он обычно не работает.
Это связано с тем, как мы общаемся по протоколу HTTP.
Когда клиент отправляет HTTP-запрос на сервер, первое, что происходит, это установление соединения. Затем сервер обрабатывает запрос и выдает ответ, который затем отправляется обратно клиенту.
После получения ответа соединение умирает.
Поэтому, как правило , вы получаете один ответ на запрос.
Распространенное заблуждение состоит в том, что с использованием ранее keep-alive
заголовка keep-alive
для постоянных подключений вы можете продолжать нажимать контент, поскольку сокет остается открытым. HTTP на самом деле не работает таким образом и потребует немного больше манипуляций, прежде чем вы сможете передавать свои данные.
Но больше об этом здесь и здесь .
Что ты можешь сделать?
Есть несколько вариантов, о которых я могу думать.
- Используя язык на стороне клиента (как правило, JavaScript), мы можем продолжать отправлять объекты
XMLHttpRequest
для запроса сервера на основе каждого полученного нами ответа, эффективно создающего поток мультимедиа. - Comet – довольно широкий термин, позволяющий веб-серверам передавать данные обратно клиенту по HTTP-запросам. APE является одной из реализаций этого.
- Посмотрите на веб-сокеты, используя Ratchet .
- Вы могли бы теоретически, и если бы вы знали адрес своего клиента, напишите API с обеих сторон, которые будут принимать cURL и XHR. В этом случае обе стороны будут выступать в роли клиентов и серверов и могут общаться на одном уровне. Это возможно с PHP, но не лучшим решением для браузеров.
Наконец, вы можете прочитать этот популярный ответ, который проходит через некоторые из этих технологий.
Проще говоря:
<style> div:not(:last-child) { display:none } </style> <?php $x=1; while($x<=100) { echo "<div>Loading: $x %</div>"; $x++; } ?>
Таким образом, старые <div>
будут скрыты по мере появления новых.
Этот скрипт работает с PHP 5.4 и Nginx на стороне сервера и протестирован с Firefox на стороне клиента. Он не работает с Chrome.
Демо на YouTube
Советы
- только один запрос
- соединение должно оставаться открытым
- для отправки контента по частям ответ должен быть помечен
- вам нужно установить заголовок без буферизации для вашего веб-сервера
- php должен быть настроен для немедленного сброса
- вам нужен трюк или умное решение для записи в ту же строку в браузере
- здесь используется трюк css
<?php header('X-Accel-Buffering: no'); // nginx related - turn the output buffer off header('Content-Encoding: chunked;'); header('Transfer-Encoding', 'chunked'); header('Content-Type', 'text/plain'); header('Connection', 'keep-alive'); function dump_chunk($chunk) { printf("%s\r\n", $chunk); flush(); ob_flush(); // if you comment this out, the chunk updates are slower } ob_start(); ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>A Chunked Response</title> <style> div:not(:last-child) { display:none; } </style> </head> <body> <?php // inital clear all ob_end_flush(); flush(); ob_flush(); // browser padding echo str_pad('', 4096) . "\n"; flush(); ob_flush(); for ($i = 0; $i < 1000; $i++) { usleep(15000); dump_chunk('<div>Sending data chunk ' . ($i + 1) . ' of 1000 <br /></div>'); } usleep(10000); // this is needed for the last update ?> </body> </html>
Я не знаю, действительно ли я понимаю ваш вопрос, но я делал что-то, что обычно люди не знают об этом. Чтобы создать впечатление, что строка перезаписывается, вы можете вставить CR (возврат каретки, «\ r») перед вашим выходом. Я записал это на примере:
<?php $x=1; while($x<=100) { echo "\rLoading: $x %"; usleep(10000); $x++; } ?>
Запустив это на терминале, я получаю прохладный статус загрузки: $ php code.php
Надеюсь, это то, что вы искали.
Нет, вы не можете сделать это без помощи javascript или jquery.
У вас может быть php-страница, если вам нужно, и это вернет прогресс, как показано ниже,
//yourprogresspage.php <?php $x="your progress"; echo "Loading: $x %<br>"; ?>
то вам нужно вызвать его со своей страницы, используя jquery
<script> var repeater; function updateprogress() { $.post( "yourprogresspage.php", function( data ) { $( ".progressdiv" ).html( data ); }); repeater = setTimeout(updateprogress, 1000); } updateprogress(); </script>
Я использовал немного CSS и HTML, вот что я придумал:
<html> <?php $x=1; while($x<=100) { ?> <div id="count"style="position:absolute;top:10px;left:10px;"> <style> #count:after { content:'<?php echo "Loading: $x % "; ?>'; } </style> </div> <?php $x++; sleep(1); } ?> </html>
в<html> <?php $x=1; while($x<=100) { ?> <div id="count"style="position:absolute;top:10px;left:10px;"> <style> #count:after { content:'<?php echo "Loading: $x % "; ?>'; } </style> </div> <?php $x++; sleep(1); } ?> </html>
того, как<html> <?php $x=1; while($x<=100) { ?> <div id="count"style="position:absolute;top:10px;left:10px;"> <style> #count:after { content:'<?php echo "Loading: $x % "; ?>'; } </style> </div> <?php $x++; sleep(1); } ?> </html>
Вам нужно обновить страницу с помощью javascript.
<?php echo '<div id="percent"></div>'; $x = 0; while($x<=100) { echo '<script type="text/javascript">document.getElementById("percent").innerHTML = '.$x.';'.'</script>'; $x++; sleep(1); }
Вы можете удалить функцию сна и выполнить свою работу.
На самом деле PHP не предоставляет такую функцию.
Чтобы показать индикатор выполнения, вы можете попробовать следующее:
Выполняя длительный процесс создания файлов, сохраните процентное значение в текущем сеансе пользователя
На странице, где показана форма загрузки, добавьте iFrame, который вызывает сценарий progress.php
Сценарий progress.php должен генерировать веб-страницу, которая должна перезагружаться автоматически-магически
Скрипт progress.php должен прочитать текущее значение прогресса из сеанса и нарисовать графику индикатора выполнения, которая визуально представляет прогресс.
Хотя это решение, основанное на PHP, вы можете подготовить еще один пример с помощью JS / AJAX.
Автозагрузка HTML должна выглядеть следующим образом:
После прочтения комментариев и ответов каждого, говорящих, что это невозможно с помощью PHP, я подумал, что я потрачу минутку, чтобы доказать их неправоту: P
Я не рекомендую фактически использовать это (потому что есть, конечно, лучшие способы достижения индикатора прогресса загрузки), но это будет «отменить эхо» предыдущей строки, если у вас нет сжатия zlib, включенного в PHP:
<?php $x = 0; echo "<html><body>"; echo "<div style=\"position: fixed; color: white; background-color: rgba(0,0,0,0.5); top: 0; left: 0;\" id=\"loader0\">Loading: 0%</div>"; ob_implicit_flush(true); //Forces all output to immediately send while($x < 100) { $x++; //Padding the string overcomes browser caching and TCP packet delays due to insufficiently sized packets echo str_pad("<div style=\"position: fixed; color: white; background-color: rgba(0,0,0,0.5); top: 0; left: 0;\" id=\"loader{$x}\">Loading: {$x}%<script>var prev = document.getElementById('loader".($x-1)."'); prev.parentNode.removeChild(prev)</script></div>", 4096, " "); sleep(1); //Just for demo } ?>
Я не вижу другого способа отправки нескольких запросов на один и тот же скрипт и сохранения процента прогресса в сеансе. Это может быть чисто PHP и HTML-решение.
<?php session_start(); if(isset($_SESSION['progress'])) $progress = $_SESSION['progress'] = $_SESSION['progress'] + 10; else $progress = $_SESSION['progress'] = 10; if($progress < 100){ echo '<head><meta http-equiv="refresh" content="1; url=http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'" /></head> <body>'.$progress.'%</body>'; } else { echo 'Done'; }
} else {<?php session_start(); if(isset($_SESSION['progress'])) $progress = $_SESSION['progress'] = $_SESSION['progress'] + 10; else $progress = $_SESSION['progress'] = 10; if($progress < 100){ echo '<head><meta http-equiv="refresh" content="1; url=http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'" /></head> <body>'.$progress.'%</body>'; } else { echo 'Done'; }
Как вы думаете ?
Вы можете использовать ob_flush();
и flush();
Это будет работать, но имейте в виду, что вы должны указать документ Charset
<meta charset="utf-8" />
а затем в начале php добавить ob_start();
в цикле скопируйте оба ob_flush();
flush();
но это будет печатать все от 1 до 100, вы должны установить php для печати
<script> document.getElementById('that div').innerHTML = "Loading [THE PERCENT]%"; </script>
Это мой собственный путь.
Так много для такого простого вопроса. На самом деле вы спрашиваете, как передать поток с сервера. Если я правильно задал вопрос, вызовите эту функцию.
function streamOutput(){ // Turn off output buffering ini_set('output_buffering', 'off'); // Turn off PHP output compression ini_set('zlib.output_compression', false); //Flush (send) the output buffer and turn off output buffering //ob_end_flush(); while (@ob_end_flush()); // Implicitly flush the buffer(s) ini_set('implicit_flush', true); ob_implicit_flush(true); //prevent apache from buffering it for deflate/gzip. for($i = 0; $i < 1000; $i++){ echo ' '; } flush(); }
Затем в вашей петле сделайте что-нибудь подобное.
$sleep = 100; for( $i = 0; $i < $sleep; $i++){ echo str_repeat('.', $i+1)." ".$i."%\n"; flush(); sleep(1); }
Важная часть здесь – вызывать флеш, когда вы хотите генерировать выходные данные. Что касается изменения DOM, когда-либо слышавшего о IFRAME, просто запустите его в iframe и все это хорошо. Iframe являются червоточинами межсетевых экранов.
это отлично работает для меня
if(!session_id()) session_start(); if($_SESSION['loding']<=100){ echo "Loading:".$_SESSION['loding']++ ."%<br>"; ?> <div style="width:<?echo $_SESSION['loding'];?>px; height:10px; background-color:green;"></div> <? //the above div content displays a green loader type effect. header( "refresh:.5; url=loaderinphp.php" ); } else{ //redirect to another page or code here }//unset the session $_SESSION['loding'] while calling again for another page load
Скриншот:
вещь о php заключается в том, что она полностью загружается и отображается как содержимое html.
(то есть)
echo "1"; usleep(5000000); echo "2";
здесь одновременно отображаются оба эхо-заявления, но время загрузки страницы увеличивается, когда вы увеличиваете время в функции usleep.
поэтому мы должны делать запрос сервера каждый раз, когда мы увеличиваем значение в загружаемом контенте.
как вы уже знаете, что это можно сделать с помощью javascript, jquery, ajax, я пробовал это с помощью сеанса.
надеюсь, это пригодится …
Не возможно только с PHP, но это может быть достигнуто с помощью PHP + JS, попробуйте привести пример,
<?php ob_start(); ob_implicit_flush(); ob_end_flush(); ?> <html> <head> <title>Loader Test</title> <script type="text/javascript"> function updateLoader(val) { document.getElementById('loader').innerHTML = "Loading:" + val + "%"; } </script> </head> <body> <div id="loader"></div> <?php flush();ob_flush(); ?> <?php for( $i = 1 ; $i <= 100 ; $i++ ) { echo '<script type="text/javascript">updateLoader('.($i).')</script>'; flush(); ob_flush(); usleep(50000); } ?> <?php ob_end_flush(); ?> <p>Completed</p> </body> </html>
Примечание. Это не будет работать, если включено zlib.output_compression или какое-либо антивирусное программное обеспечение хранит буфер до тех пор, пока страница не будет загружена до отправки в браузер.
Допустим, у страницы есть большие данные для загрузки, поэтому вы хотите загрузчика.
Вы можете заставить пользователя подумать, что есть загрузчик.
<?php // Loader last id $loader_id = 0; // Initiate loader function initLoader(){ echo '<style>.php_loader{width:100px;height:50px;line-height:50px;margin-top:-25px;margin-left:-50px;position:fixed;top:50%;left:50%;}</style>'; // Load first loader echo '<div id="php_loader_'.$GLOBALS['loader_id'].'" class="php_loader">0%</div>'; } // Upadate loader function updateLoader($percent){ // Remove last loader clearLoader(); // Insert new loader $GLOBALS['loader_id']++; echo '<div id="php_loader_'.$GLOBALS['loader_id'].'" class="php_loader">'.$percent.'%</div>'; ob_flush(); flush(); } function clearLoader(){ // Remove last loader echo '<style>#php_loader_'.$GLOBALS['loader_id'].'{display:none;}</style>'; } ?> <html> <head> <title>Server Side Loader</title> </head> <body style="padding:30px; font-size:30px;font-family: Courier;"> <?php // On body start we init loader initLoader(); sleep(1); ?> 25% off the page just loaded</br> <?php updateLoader(25); sleep(1); ?> 30% off the page just loaded</br> <?php updateLoader(30); sleep(1); ?> 50% off the page just loaded</br> <?php updateLoader(50); sleep(1); ?> 80% off the page just loaded</br> <?php updateLoader(80); sleep(1); ?> 100% off the page just loaded</br> <?php updateLoader(100); sleep(1); // Clear loader before body clearLoader(); ?> </body> </html>
Хороший и гладкий.
Это действительно зависит от того, как вы выполняете загрузку, но что можете сделать, если вы действительно хотите использовать AJAX js для сохранения открытого соединения и каждого обновления из обработки на внутреннем сервере, чтобы обновить интерфейс с помощью JS, который обновил правильную отображать виджет / поле в обратном вызове AJAX .
Если вы просто хотите сделать это с помощью PHP, вы можете легко сделать следующее:
<?php $x=1; while($x<=100) { echo "Loading: $x %<br>"; $x++; <CALL THE FUNCTION THAT DOES THE ACTUAL PROCESSING HERE> ob_end_clean(); }
Чтобы добавить к этому вопросу, вы можете использовать выходную буферизацию, если вы действительно хотели этого достичь (это не рекомендуется). Единственное ограничение заключается в том, что вы не можете перезаписать предыдущий вывод. Это больше похоже на индикатор выполнения:
<?php while(@ob_get_clean()); echo "Loading: "; for($i=0; $i<10; $i++) { echo str_pad("+", 4096); usleep(200000); } echo "Done."; ?>
в<?php while(@ob_get_clean()); echo "Loading: "; for($i=0; $i<10; $i++) { echo str_pad("+", 4096); usleep(200000); } echo "Done."; ?>
См. Вывод вывода в частях на PHP .
Решение, не лучшее для разработчика, но оно будет работать именно так, как вы хотите. Вы сценарий в порядке. Но если вы видите весь результат вообще, и вы не видите прогресс, это потому, что есть буферный механизм. Возможно, php, возможно, веб-сервер (apache …) или даже, возможно, буфер браузера.
Взгляните на флеш-функцию flush (). Чтобы проверить, вам нужно использовать «браузер командной строки» (возможно, запрос telnet / GET вручную). Если в командной строке отображается строка, следующая за строкой, то проблема связана с вашим веб-браузером.
Но сначала вам нужно определить, где WHERE – текущий буферный механизм: php output? (см. функцию flush php), сжатие веб-сервера? (см. сжатие gzip), возможно, буферизация браузера? (хром ждет окончания файла, прежде чем показывать результаты)