Portada Blogs Álbumes Notas Herramientas Usuarios Ayuda |
Blog de BLei couRT (cambiar): Página Principal Entradas Historial Estadísticas |
<< Anterior | Link Permanente | Compartir en Facebook | Siguiente >> |
Entrada 1 de 1
Ahora contaré como ocurrió, pero antes explicaré la razón de está página fuera de la planificación...
Resulta que me vi en la necesidad de conocer el progreso de envío de un archivo desde el lado del cliente mientras el envío tiene lugar (como hace, por ejemplo, youtube cuando subimos un vídeo mostrando una barrita de progreso). Por desgracia, la única forma (presunta) posible de hacer esto es usando cgis o módulos en otros lenguajes diferentes a php (como perl). Como yo odio tener que mezclar unas cosas con otras, o usar bombas termonucleares para matar moscas, busqué si había alguna opción para hacerlo desde php sin guarrear mucho. Mi ilusión vino cuando encontré un método que podía usarse desde PHP 5.2 junto con la extensión APC (Alternative PHP Cache); la pega es que la documentación de esta extensión es escasa, y la poca que hay está en ingles, así que he dedico hacer esta miniguia con todo el proceso para quien pueda serle útil. Pero antes... ¿a raíz de qué vino esta necesidad?. Todo sucedió porque Axel tuvo el detalle de subir las fotos del cumpleaños de Carlos (250 megas) al almacen de archivos de log85 (con su cuenta log87) para evitarme, así, tiempos de espera en megaupload entre paquete y paquete (quería bajar otras cosas desde allí y no soy premium). Al final los dos acabamos desesperados debido a la lentitud (¡no por el l85!, hubiera tardado lo mismo en megaupload; es cosa de las ridículas velocidades de transmisión salientes de las conexiones en España y mi bajada (que es su subida) es varios órdenes de magnitud superior). Uno de los comentarios que me hizo Axel fue "esto no tira, se ha petao", a pesar de que todo iba bien y que un mensaje parpadeante decía "cargando... ¡espera!". Entendí entonces que la gente si no ve "un progreso real" tiende a pensar que las cosas se han bloqueado, y que debería arreglar eso como sea. Decidí hacer una barra de progreso total, y contadores con la velocidad y los tiempos, tal que así: De esta forma, nadie que vea avanzar el progreso y variar en tiempo real las velocidades, podrá tener la sensación de bloqueo. Y ahora, veremos como se hace... (***) Como ya hemos dicho, PHP por si solo no proporciona ningún mecanismo para acceder a los archivos crudos mientras se suben. Para esto vamos a tener que instalar una extensión de PHP que, en cualquier caso, es lo "menos" ajeno que podemos hacer. La extensión es APC, sirve para cachear la compilación al vuelo de los fuentes de php aumentando el rendimiento considerablemente. Además nos proporciona un mecanismo descrito en el rfc1867 para acceder a los archivos crudos mientras se suben al servidor. APC normalmente se instala con el paquete "apc", pero en mi gentoo el paquete es "pecl-apc", en cualquier caso una búsqueda de "apc" en vuestro gestor de paquetes debería daros el nombre correcto: emerge pecl-apc Una vez instalado es hora de configurarlo. En mi gentoo se crea automáticamente el archivo /etc/php/apache2-php5/ext-active/apc.ini, el cual se procesa justo después de php.ini. Si no tenéis un archivo de configuración concreto para apc, debéis añadir la configuración a php.ini. A continuación pongo mi configuración y comento las líneas importantes: Configuración: extension=apc.so //Define el nombre de la librería dinámica apc.enabled="1"//Activa el uso de APC, si es 0 APC no funcionará apc.shm_segments="1" apc.shm_size="30" apc.num_files_hint="1024" apc.ttl="7200" apc.user_ttl="7200" apc.gc_ttl="3600" apc.cache_by_default="1" ;apc.filters="" ;apc.mmap_file_mask="/tmp/apcphp5.XXXXXX" apc.slam_defense="0" apc.file_update_protection="2" apc.enable_cli="0" apc.max_file_size="1M" apc.stat="1" apc.write_lock="1" apc.report_autofilter="0" apc.include_once_override="0" apc.rfc1867="1" //Esta línea debemos activarla para tener acceso a los archivos mientras se suben (off por defecto) apc.rfc1867_prefix="upload_" //Prefijo a usar con los ids de los archivos apc.rfc1867_name="APC_UPLOAD_PROGRESS" apc.rfc1867_freq="0" apc.localcache="0" apc.localcache.size="512" apc.coredump_unmap="0" Una vez todo configurado, reiniciamos el servidor e iniciamos las pruebas. Para que todo funciona, debemos poner justo antes del input file que queramos monitorizar la siguiente línea html: <input type="hidden" name="APC_UPLOAD_PROGRESS" value="id_archivo"> id_archivo debe ser único en todo el server en todo el tiempo, por ello quizás deberíamos crearnos un manejador que nos abstraiga de todo el proceso y genere ids únicas. En cualquier caso, con esto ya podremos acceder desde php al archivo usando su id. Con ajax podremos llamar a otra página a la que le pasaremos el id del archivo, esa página en php devolverá los datos sobre el archivo que queramos: Importante: Desde la página hay que añadir el prefijo "upload_" al id del archivo. $upload=apc_fetch("upload_$clave"); if($upload) { if($upload['done']) $percent=100; else if($upload['total']==0) $percent=0; else $percent=$upload['current']/$upload['total']*100; } echo $percent; El campo current muestra cuantos bytes han sido subidos desde el archivo, y el campo total muestra el tamaño total del archivo; el campo done es un booleano que muestra si el archivo ha terminado de subirse. Con estos datos ya podemos calcular el porcentaje, y si usamos, desde el cliente, temporizadores y un registro de los datos (por ejemplo, comprobamos cuánto del archivo se ha subido cada 2 segundos), podremos calcular cosas como el tiempo restante estimado, la velocidad actual, la velocidad media, etc. (***) En una tarde tuve el sistema funcionando y, en la próxima actualización del motor del log85, todos los almacenes tendrán esta función. Espero que le sea útil a alguien :) Archivado en: PHP.
|
Páginas
Puntuación
WARNING!!! About... Estadísticas
5649 Días
1778 Visitas
8 Posts
Postea una de
cada 222 visitas Licencia
|