TigerZF
🌐Español

Capítulo 56. Zend_ProgressBar

56.1. Zend_ProgressBar

56.1.1. Introducción

Zend_ProgressBar es un componente para crear y actualizar barras de progreso en diferentes entornos. Consiste en un único backend, que muestra el progreso a través de uno de los múltiples adaptadores. En cada actualización, toma un valor absoluto y opcionalmente un mensaje de estado, y luego llama al adaptador con algunos valores precalculados como el porcentaje y el tiempo restante estimado.

56.1.2. Uso básico de Zend_Progressbar

Zend_ProgressBar es bastante sencillo de usar. Simplemente crea una nueva instancia de Zend_Progressbar, definiendo un valor mínimo y uno máximo, y elige un adaptador para mostrar los datos. Si deseas procesar un archivo, harías algo como:

$progressBar = new Zend_ProgressBar($adapter, 0, $fileSize);

while (!feof($fp)) {
    // Do something

    $progressBar->update($currentByteCount);
}

$progressBar->finish();

En el primer paso, se crea una instancia de Zend_ProgressBar, con un adaptador específico, un valor mínimo de 0 y un valor máximo equivalente al tamaño total del archivo. Luego se procesa un archivo y en cada bucle la barra de progreso se actualiza con el conteo actual de bytes. Al final del bucle, el estado de la barra de progreso se establece como terminado.

También puedes llamar al método update() de Zend_ProgressBar sin argumentos, lo que simplemente recalcula el ETA y notifica al adaptador. Esto es útil cuando no hay una actualización de datos, pero quieres que la barra de progreso se actualice.

56.1.3. Progreso persistente

Si deseas que la barra de progreso sea persistente entre varias peticiones, puedes indicar el nombre de un espacio de nombres de sesión como cuarto argumento del constructor. En ese caso, la barra de progreso no notificará al adaptador dentro del constructor, sino solo cuando llames a update() o finish(). Además, el valor actual, el texto de estado y la hora de inicio para el cálculo del ETA se recuperarán de nuevo en la siguiente ejecución de la petición.

56.1.4. Adaptadores estándar

Zend_ProgressBar viene con los siguientes tres adaptadores:

56.1.4.1. Zend_ProgressBar_Adapter_Console

Zend_ProgressBar_Adapter_Console es un adaptador basado en texto para terminales. Puede detectar automáticamente el ancho del terminal, pero también admite anchos personalizados. Puedes definir qué elementos se muestran con la barra de progreso y también personalizar el orden de los mismos. También puedes definir el estilo de la propia barra de progreso.

[Note] Reconocimiento automático del ancho de la consola

shell_exec es necesario para que esta funcionalidad funcione en sistemas *nix. En Windows, siempre hay un ancho de terminal fijo de 80 caracteres, por lo que no se necesita reconocimiento allí.

Puedes establecer las opciones del adaptador ya sea a través de los métodos set* o proporcionando un array o una instancia de Zend_Config con las opciones como primer parámetro del constructor. Las opciones disponibles son:

  • outputStream: Un flujo de salida diferente, si no deseas transmitir a STDOUT. Puede ser cualquier otro flujo como php://stderr o una ruta a un archivo.

  • width: Ya sea un entero o la constante AUTO de Zend_Console_ProgressBar.

  • elements: Ya sea NULL para el valor por defecto o un array con al menos una de las siguientes constantes de Zend_Console_ProgressBar como valor:

    • ELEMENT_PERCENT: El valor actual en porcentaje.

    • ELEMENT_BAR: La barra visual que muestra el porcentaje.

    • ELEMENT_ETA: El ETA calculado automáticamente. Este elemento se muestra por primera vez después de cinco segundos, porque en ese tiempo no es posible calcular resultados precisos.

    • ELEMENT_TEXT: Un mensaje de estado opcional sobre el proceso actual.

  • textWidth: Ancho en caracteres del elemento ELEMENT_TEXT. El valor por defecto es 20.

  • charset: Charset del elemento ELEMENT_TEXT. El valor por defecto es utf-8.

  • barLeftChar: Una cadena que se utiliza a la izquierda del indicador en la barra de progreso.

  • barRightChar: Una cadena que se utiliza a la derecha del indicador en la barra de progreso.

  • barIndicatorChar: Una cadena que se utiliza para el indicador en la barra de progreso. Esta puede estar vacía.

56.1.4.2. Zend_ProgressBar_Adapter_JsPush

Zend_ProgressBar_Adapter_JsPush es un adaptador que permite actualizar una barra de progreso en un navegador mediante Javascript Push. Esto significa que no se requiere una segunda conexión para recopilar el estado de un proceso en ejecución, sino que el propio proceso envía su estado directamente al navegador.

Puedes establecer las opciones del adaptador ya sea a través de los métodos set* o proporcionando un array o una instancia de Zend_Config con las opciones como primer parámetro del constructor. Las opciones disponibles son:

  • updateMethodName: El método javascript que debe llamarse en cada actualización. El valor por defecto es Zend_ProgressBar_Update.

  • finishMethodName: El método javascript que debe llamarse después de que se establezca el estado de finalización. El valor por defecto es NULL, lo que significa que no se hace nada.

El uso de este adaptador es bastante sencillo. Primero creas una barra de progreso en tu navegador, ya sea con JavaScript o creada previamente con HTML plano. Luego defines el método de actualización y opcionalmente el método de finalización en JavaScript, ambos recibiendo un objeto json como único argumento. Luego llamas a una página web con el proceso de larga duración en un iframe o etiqueta object oculta. Mientras el proceso está en ejecución, el adaptador llamará al método de actualización en cada actualización con un objeto json, que contiene los siguientes parámetros:

  • current: El valor absoluto actual

  • max: El valor absoluto máximo

  • percent: El porcentaje calculado

  • timeTaken: El tiempo que el proceso lleva ejecutándose

  • timeRemaining: El tiempo esperado para que el proceso finalice

  • text: El mensaje de estado opcional, si se proporciona

Ejemplo 56.1. Ejemplo básico para la parte del cliente

Este ejemplo ilustra una configuración básica de HTML, CSS y JavaScript para el adaptador 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 + '%';
}

Esto creará un contenedor simple con un borde negro y un bloque que indica el proceso actual. No deberías ocultar el iframe u object mediante display: none;, ya que algunos navegadores como Safari 2 no cargarán el contenido real en ese caso.

En lugar de crear tu propia barra de progreso personalizada, quizás quieras usar una de las bibliotecas JavaScript disponibles como Dojo, jQuery, etc. Por ejemplo, existen:


[Note] Intervalo de actualizaciones

Debes tener cuidado de no enviar demasiadas actualizaciones, ya que cada actualización tiene un tamaño mínimo de 1kb. Este es un requisito para que el navegador Safari realmente procese y ejecute la llamada a la función. Internet Explorer tiene una limitación similar de 256 bytes.

56.1.4.3. Zend_ProgressBar_Adapter_JsPull

Zend_ProgressBar_Adapter_JsPull es lo opuesto a jsPush, ya que requiere consultar (pull) las nuevas actualizaciones, en lugar de enviarlas (push) a los navegadores. Generalmente deberías usar este adaptador con la opción de persistencia de Zend_ProgressBar. Al notificar, el adaptador envía una cadena JSON al navegador, que se ve exactamente igual que la cadena JSON enviada por el adaptador jsPush. La única diferencia es que contiene un parámetro adicional, finished, que es FALSE cuando se llama a update() o TRUE, cuando se llama a finish().

Puedes establecer las opciones del adaptador ya sea a través de los métodos set*() o proporcionando un array o una instancia de Zend_Config con las opciones como primer parámetro del constructor. Las opciones disponibles son:

  • exitAfterSend: Sale de la petición actual después de que los datos se hayan enviado al navegador. El valor por defecto es TRUE.