Zend_ProgressBar
to komponent służący do tworzenia i
aktualizacji pasków postępu (progressbar) w różnych środowiskach. Składa się na niego
pojedynczy element backendu, który sygnalizuje postęp poprzez jeden z wielu
dostępnych adapterów. Podczas każdej aktualizacji brana jest wartość absolutna i
opcjonalna wiadomość o stanie postępu a następnie skonfigurowany adapter
jest wywoływany z obliczonymi danymi takimi jak procent postępu
oraz czas, jaki został do końca wykonywanej akcji.
Zend_ProgressBar
jest komponentem łatwym w użyciu. Należy,
po prostu, utworzyć nową instancję klasy Zend_Progressbar
,
definiując wartość minimalną i maksymalną oraz wybrać adapter służący prezentacji
danych o postępie działań. W przypadku operacji na pliku, użycie może wyglądać
następująco:
$progressBar = new Zend_ProgressBar($adapter, 0, $fileSize); while (!feof($fp)) { // Wykonanie operacji $progressBar->update($currentByteCount); } $progressBar->finish();
W pierwszym kroku tworzona jest instancja Zend_ProgressBar
ze zdefiniowanym adapterem, wartością minimalną: 0, oraz maksymalną równą
rozmiarowi pliku. Po tym następuje seria operacji na pliku w pętli.
Podczas każdej iteracji pętli, pasek postępu jest aktualizowany danymi o
ilości "przerobionych" bajtów pliku.
Metodę update()
klasy Zend_ProgressBar
można również wywoływać bez argumentów. Powoduje to przeliczenie czasu do końca
wykonywanej akcji i wysłanie go do adaptera. Ten sposób może być przydatny gdy nie
ma konkretnych danych do wysłania adapterowi ale niezbędna jest aktualizacja
paska postępu.
Jeśli zajdzie potrzeba utrzymania paska postępu przez wiele żądań, można w tym celu
podać łańcuch znaków z przestrzenią nazw sesji
jako czwarty argument konstruktora. W tym przypadku
pasek postępu nie uaktualni adaptera w momencie konstruowania - niezbędne będzie
wywołanie metody update()
lub finish()
.
Obecna wartość, tekst stanu postępu oraz czas rozpoczęcia działania
(wymagany przy obliczaniu czasu pozostałego do końca) będą pobrane podczas następnego
żądania i uruchomienia skryptu.
Standardowo Zend_ProgressBar
ma do dyspozycji następujące
adaptery:
Zend_ProgressBar_Adapter_Console
to adapter tekstowy przeznaczony
do użytku z terminalem (konsolą, wierszem polecenia). Adapter potrafi automatycznie wykryć
dostępną szerokość ale można również podać ją ręcznie. Oprócz tego można definiować
elementy, jakie mają zostać pokazane oraz ich kolejność jak również sam styl wyświetlanego
paska postępu.
Automatyczne rozpoznawanie szerokości konsoli
W przypadku systemów *nix niezbędny dla tej funkcjonalności jest
shell_exec
. Na maszynach Windows szerokość terminala jest stała
(wynosi 80 znaków) więc automatyczne rozpoznawanie szerokości nie jest potrzebne.
Opcje adaptera można ustawiać za pomocą metod set*
albo przez podanie
tablicy asocjacyjnej lub obiektu Zend_Config
w pierwszym parametrze
konstruktora. Dostępne opcje to:
-
outputStream
: Strumień do którego będzie kierowany wynik. Domyślnie to STDOUT. Może być dowolnym strumieniem, np.:php://stderr
lub ścieżką do pliku. -
width
: Liczba całkowita lub stałaAUTO
klasyZend_Console_ProgressBar
. -
elements
: PrzyjmujeNULL
dla domyślnej konfiguracji lub tablicę zawierającą co najmniej jedną z następujących wartości:-
ELEMENT_PERCENT
: Obecna wartość wyrażona procentowo -
ELEMENT_BAR
: Pasek pokazujący wartość procentową. -
ELEMENT_ETA
: Automatycznie obliczany czas do zakończenia operacji. Ten element jest pokazywany pierwszy raz z opóźnieniem 5 sekund bo w krótszym czasie nie ma możliwości obliczenia wiarygodnych wyników. -
ELEMENT_TEXT
: Opcjonalna wiadomość stanu postępu operacji.
-
-
textWidth
: Szerokość elementuELEMENT_TEXT
podana w znakach. Domyślnie to 20. -
charset
: Kodowanie elementuELEMENT_TEXT
. Domyślnie to utf-8. -
barLeftChar
: Łańcuch znaków używany jako lewa krawędź paska postępu. -
barRightChar
: Łańcuch znaków używany jako prawa krawędź paska postępu. -
barIndicatorChar
: Łańcuch znaków używany jako wskaźnik paska postępu. Może zostać pusty.
Zend_ProgressBar_Adapter_JsPush
to adapter pozwalający na
aktualizację paska postępu w przeglądarce poprzez JavaScript Push. To oznacza, że
nie jest potrzebne nowe połączenie na potrzeby przesyłu danych o postępie operacji.
Proces pracujący po stronie serwera komunikuje się bezpośrednio z przeglądarką
użytkownika.
Opcje adaptera można ustawiać za pomocą metod set*
albo przez podanie
tablicy asocjacyjnej lub obiektu Zend_Config
w pierwszym parametrze
konstruktora. Dostępne opcje to:
-
updateMethodName
: Metoda JavaScript, która zostanie wywołana przy każdej aktualizacji paska postępu. Domyślnie jest toZend_ProgressBar_Update
. -
finishMethodName
: Metoda JavaScript, która zostanie wywołana po zakończeniu prowadzonej operacji. Domyślna wartość toNULL
, co oznacza brak reakcji.
Użycie tego adaptera jest dość proste. Na początku należy utworzyć pasek postępu w
przeglądarce za pomocą poleceń JavaScript lub HTML. Następnie należy
zdefiniować metodę JavaScript wywoływaną przy aktualizacji oraz (opcjonalnie)
po skończeniu działania. Obie powinny przyjmować pojedynczy argument - obiekt
JSON. Aby otworzyć połączenie należy wywołać długo trwającą akcję
w ukrytym obiekcie iframe
lub object
. Podczas wykonywania
tego procesu przy każdej aktualizacji adapter będzie wywoływał odpowiednią metodę
przekazując do niej obiekt JSON o następujących parametrach:
-
current
: Obecna wartość absolutna -
max
: Maksymalna wartość absolutna -
percent
: Obliczony procent postępu -
timeTaken
: Czas trwania procesu (do obecnej chwili) -
timeRemaining
: Oszacowanie czasu pozostałego do końca -
text
: Opcjonalna wiadomość dotycząca stanu postępu
Przykład 654. Podstawowy przykład kodu po stronie klienta
Ten przykład ilustruje prosty kod HTML, CSS oraz JavaScript do użytku z adapterem JsPush
<div id="zend-progressbar-container"> <div id="zend-progressbar-done"></div> </div> <iframe src="long-running-process.php" id="long-running-process"></iframe>
#long-running-process { position: absolute; left: -100px; top: -100px; width: 1px; height: 1px; } #zend-progressbar-container { width: 100px; height: 30px; border: 1px solid #000000; background-color: #ffffff; } #zend-progressbar-done { width: 0; height: 30px; background-color: #000000; }
function Zend_ProgressBar_Update(data) { document.getElementById('zend-progressbar-done').style.width = data.percent + '%'; }
Powyższy kod tworzy prosty pojemnik z czarną granicą oraz blok wskazujący
zaawansowanie procesu. Należy pamiętać by nie ukrywać elementów
iframe
lub object
poprzez display: none;
ponieważ w takiej sytuacji niektóre przeglądarki jak Safari 2 w ogóle nie pobiorą
tych elementów.
Zamiast własnoręcznie tworzyć pasek postępu, można skorzystać z jednej z wielu dostępnych bibliotek JavaScript, takich jak Dojo czy jQuery. Np.:
Odstęp czasowy pomiędzy aktualizacjami
Należy upewnić się, że nie jest tworzona zbyt duża ilość aktualizacji. Każda z nich powinna przesyłać dane o wielkości co najmniej 1kB. Dla przeglądarki Safari jest to niezbędny warunek do wykonania polecenia wywołania funkcji. Internet Explorer ma podobne ograniczenie - w jego przypadku jest to 256 Bajtów.
Adapter Zend_ProgressBar_Adapter_JsPull
jest przeciwieństwem
jsPush. W jego przypadku niezbędne jest "wyciągnięcie" aktualizacji
zamiast "wypchnięcia" z przeglądarki. Generalnie zaleca się użycie tego adaptera
z opcją utrwalania postępu Zend_ProgressBar
.
Jego działanie polega na wysłaniu do przeglądarki
łańcucha znaków (w formacie JSON), który wygląda tak
jak string JSON wysyłany przez adapter jsPush. Jedyną różnicą
pomiędzy nimi jest dodatkowy parametr (w stringu wysyłanym przez adapter jsPull)
o nazwie finished
. Zawiera on wartość FALSE
kiedy
uruchamiana jest metoda update()
lub TRUE
w przypadku wywoływania metody finish()
.
Opcje adaptera można ustawiać za pomocą metod set*
albo przez podanie
tablicy asocjacyjnej lub obiektu Zend_Config
w pierwszym parametrze
konstruktora. Dostępne opcje to:
-
exitAfterSend
: Flaga oznaczająca czy bieżące żądanie ma zostać zakończone po wysłaniu danych do przeglądarki. Domyślnie przyjmuje wartośćTRUE
.