Spis treści
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
|
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ła AUTO
klasy Zend_Console_ProgressBar.
elements: Przyjmuje NULL 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ść elementu ELEMENT_TEXT
podana w znakach. Domyślnie to 20.
charset: Kodowanie elementu ELEMENT_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 to
Zend_ProgressBar_Update.
finishMethodName: Metoda JavaScript, która zostanie wywołana
po zakończeniu prowadzonej operacji. Domyślna wartość to
NULL, 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 53.1. 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.