Subir barra de progreso en PHP

82

¿Alguien sabe cómo obtener una barra de progreso para una carga en php? Estoy intentando escribir código para un cargador de álbumes de fotos. Me gustaría que se muestre una barra de progreso mientras se cargan las fotos.

Soy bastante nuevo en php, así que no sé todo al respecto.

Josh Curren
fuente

Respuestas:

70

Este es, con mucho, (después de horas de buscar en Google y probar scripts) el más simple de configurar y el mejor cargador que he encontrado

https://github.com/FineUploader/fine-uploader

No requiere APC ni ninguna otra biblioteca PHP externa, puedo obtener comentarios sobre el progreso del archivo en un host compartido y afirma ser compatible con la función de arrastrar y soltar html5 (no probado personalmente) y la carga de múltiples archivos.

Jesse
fuente
11
Creo que querrás usar esto en su lugar: github.com/valums/file-uploader - mismo autor.
Michael Reed
5
Y consulte Progreso de carga de la sesión, que es lo que ofrece PHP para obtener el progreso de la carga de un archivo listo para usar.
hakre
6
@jpeskin eso es un poco injusto para el desarrollador. el hecho de que usted "se ofrezca a pagarles" no los obliga, como una especie de prostituta, a trabajar para usted. Si no puede averiguar cómo depurarlo, entonces no iría por ahí señalando con el dedo a nadie más que a usted mismo: el software que encuentra en Internet se proporciona "tal cual", así que no golpee a las personas que lo están haciendo nada más que tratar de ayudar.
sucitivel
3
@sucitivel Para ser más detallado: me ofrecí a pagar y él aceptó, luego nos tomamos la molestia de documentar todos los errores que estábamos viendo, y luego dejó de responder a todos y cada uno de los correos electrónicos (simplemente amables, solicitando una actualización de estado y si todavía estaba interesado en el trabajo). No considero a nadie obligado a trabajar por dinero. Era simplemente un punto de datos de observación para otros que podrían querer saber sobre la disponibilidad y / o interés del desarrollador en el trabajo independiente. El proyecto se bifurcó, por lo que no fui el único que sintió que el desarrollador estaba perdiendo interés en mantener.
jpeskin
5
blueimp.github.com/jQuery-File-Upload : esto funciona realmente bien. Al menos me gusta, ya que no se queda atrás en Ubuntu =)
BeRocket
13

Si tiene APC instalado, tiene un gancho de devolución de llamada para el progreso de la carga.

Rasmus Lerdorf (creador de PHP) tiene una muestra de esto usando YUI (ah, y aquí está la fuente de PHP ).

Consulte la documentación aquí .

Señor de poder
fuente
Ya no funcionan los mismos o los enlaces fuente php .. ¿tienes un enlace alternativo por favor?
supersan
@supersan Esta respuesta está muy desactualizada. APC está muerto y la API de carga de sesiones es ahora algo independiente . Tampoco funciona si el servidor utiliza FastCGI ... lo que la mayoría lo hace por razones de seguridad en estos días.
Powerlord
13

Lamento decir que, a mi leal saber y entender, una barra de progreso de carga de PHP pura, o incluso una barra de progreso de carga de PHP / Javascript, no es posible debido a cómo funciona PHP. Su mejor opción es utilizar algún tipo de cargador Flash.

AFAIK Esto se debe a que su script no se ejecuta hasta que todas las superglobales estén pobladas, lo que incluye $ _FILES. Para cuando se llama a su script PHP, el archivo está completamente cargado.

EDITAR: Esto ya no es cierto. Fue en 2010.

Macha
fuente
13
¿Por qué los tres votos negativos? Es cierto y son completamente injustificados. Desafío a cualquiera a que me muestre una barra de progreso que se ejecute en PHP nativo y que no necesite extensiones adicionales / módulos Apache / scripts perl / otras cosas para funcionar.
Pekka
1
Bueno, es 2011 y ahora es posible gracias a HTML5. Vea la primera respuesta aquí: stackoverflow.com/questions/76976/…
Zarel
10
Bueno, es 2012 y la carga de archivos en HTML5 a través de XMLHttpRequest aún no está disponible en todos los navegadores principales.
Damien B
3
@Pekka 웃 No es cierto. Si tiene APC instalado (y debería hacerlo), puede hacerlo de forma completamente nativa en PHP, y tampoco javascript.
Ariel
2
@Pekka 웃 Sin mencionar la carga usando información de sesión en PHP> = 5.4.
Wookie88
8

Una forma PHP-ish (5.2+) y sin Flash que funcionó muy bien para mí:

Primero, vea esta publicación que explica cómo poner en funcionamiento la extensión "uploadprogress".

Luego, en la página que contiene el formulario desde el que está cargando archivos, cree el siguiente iframe:

<iframe id="progress_iframe" src="" style="display:none;" scrolling="no" frameborder="0"></iframe>

A continuación, agregue este código a su botón "Enviar":

onclick="function set() { f=document.getElementById('progress_iframe'); f.style.display='block'; f.src='uploadprogress.php?id=<?=$upload_id?>';} setTimeout(set);"

Ahora tiene un iframe oculto en su formulario que se hará visible y mostrará el contenido de uploadprogress.php cuando haga clic en "Enviar" para comenzar a cargar archivos. $ upload_id debe ser el mismo que está utilizando como valor del campo oculto "UPLOAD_IDENTIFIER" en su formulario.

El uploadprogress.php en sí mismo se ve así (arregle y ajuste a sus necesidades):

<html>
<head>
<META HTTP-EQUIV='REFRESH' CONTENT='1;URL=?id=<?=$_GET['id']?>'>
</head>
<body>
Upload progress:<br />
<?php
    if(!$_GET['id']) die;
    $info = uploadprogress_get_info($_GET['id']);
    $kbytes_total = round($info['bytes_total'] / 1024);
    $kbytes_uploaded = round($info['bytes_uploaded'] / 1024);
    echo $kbytes_uploaded.'/'.$kbytes_total.' KB';
?>
</body>
</html>

Tenga en cuenta que se actualiza automáticamente cada segundo. Seguramente puede agregar una barra de progreso visual agradable aquí (como 2 <div> s anidados con diferentes colores) si lo desea. El iframe con progreso de carga, naturalmente, solo funciona mientras la carga está en progreso y finaliza su vida visible una vez que se envía el formulario y el navegador se vuelve a cargar en la página siguiente.

IvarsK
fuente
¿Cómo se puede cargar un archivo sin $ _FILES en php
4

La implementación de la barra de progreso de carga es fácil y no requiere ninguna extensión adicional de PHP, JavaScript o Flash. Pero necesita PHP 5.4 y versiones posteriores .

Usted tiene que permitir la recogida de la información de progreso de carga mediante el establecimiento de la directiva session.upload_progress.enableda Onen php.ini.

Luego, agregue una entrada oculta al formulario de carga HTML justo antes de cualquier otra entrada de archivo. El atributo HTML namede esa entrada oculta debe ser el mismo que el valor de la directiva session.upload_progress.namede php.ini(eventualmente precedido por session.upload_progress.prefix). El valueatributo depende de usted, se utilizará como parte de la clave de sesión.

El formulario HTML podría verse así:

<form action="upload.php" method="POST" enctype="multipart/form-data">
   <input type="hidden" name="<?php echo ini_get('session.upload_progress.prefix').ini_get('session.upload_progress.name'); ?>" value="myupload" />
   <input type="file" name="file1" />
   <input type="submit" />
</form>

Cuando envíe este formulario, PHP debería crear una nueva clave en la $_SESSIONestructura superglobal que se completará con la información del estado de carga. La clave está concatenada nameyvalue de la entrada oculta.

En PHP puede echar un vistazo a la información de carga completa:

var_dump($_SESSION[
    ini_get('session.upload_progress.prefix')
   .ini_get('session.upload_progress.name')
   .'_myupload'
]);

La salida tendrá un aspecto similar al siguiente:

$_SESSION["upload_progress_myupload"] = array(
  "start_time" => 1234567890,   // The request time
  "content_length" => 57343257, // POST content length
  "bytes_processed" => 54321,   // Amount of bytes received and processed
  "done" => false,              // true when the POST handler has finished, successfully or not
  "files" => array(
    0 => array(
      "field_name" => "file1",    // Name of the <input /> field
      // The following 3 elements equals those in $_FILES
      "name" => "filename.ext",
      "tmp_name" => "/tmp/phpxxxxxx",
      "error" => 0,
      "done" => false,            // True when the POST handler has finished handling this file
      "start_time" => 1234567890, // When this file has started to be processed
      "bytes_processed" => 54321, // Number of bytes received and processed for this file
    )
  )
);

Hay toda la información necesaria para crear una barra de progreso: tiene la información si la carga aún está en progreso, la información de cuántos bytes se transferirán en total y cuántos bytes ya se han transferido.

Para presentar el progreso de la carga al usuario, escriba un script PHP diferente al de carga, que solo verá la información de carga en la sesión y la devolverá en formato JSON, por ejemplo. Este script se puede llamar periódicamente, por ejemplo, cada segundo, utilizando AJAX y la información presentada al usuario.

Incluso puede cancelar la carga configurando $_SESSION[$key]['cancel_upload']a true.

Para obtener información detallada, configuraciones adicionales y comentarios del usuario, consulte el manual de PHP .

David Ferenczy Rogožan
fuente
2

Otro cargador completo JS: http://developers.sirika.com/mfu/

  • Es gratis (licencia BSD)
  • Internacionalizable
  • compatible con varios navegadores
  • tiene la opción de instalar APC o no (barra de progreso indeterminada VS barra de progreso determinada)
  • Aspecto personalizable ya que utiliza un mecanismo de plantilla de dojo. Puede agregar su clase / ID en las plantillas te de acuerdo con su css

que te diviertas

Valdelievre
fuente
2

HTML5 introdujo una API de carga de archivos que le permite monitorear el progreso de las cargas de archivos, pero para los navegadores más antiguos, existe un marco de plupload diseñado específicamente para monitorear las cargas de archivos y brindar información sobre ellos. además, tiene muchas devoluciones de llamada para que funcione en todos los navegadores

el maestro
fuente
2

Gears y HTML5 tienen un evento de progreso en el HttpRequestobjeto para enviar una carga de archivo a través de AJAX.

http://developer.mozilla.org/en/Using_files_from_web_applications

Sus otras opciones ya respondidas por otros son:

  1. Cargador basado en Flash.
  2. Cargador basado en Java.
  3. Una segunda solicitud estilo cometa al servidor web o un script para informar el tamaño de los datos recibidos. Algunos servidores web como Lighttpd proporcionan módulos para hacer esto en el proceso para ahorrar la sobrecarga de llamar a un proceso o script externo.

Técnicamente, hay una cuarta opción, similar a la carga de YouTube, con Gears o HTML5 puedes usar blobs para dividir un archivo en pequeños fragmentos y subir cada fragmento individualmente. Al finalizar cada fragmento, puede actualizar el estado de progreso.

Steve-o
fuente
1

Necesitaría usar Javascript para crear una barra de progreso. Una simple búsqueda en Google me llevó a este artículo: Barra de progreso de Javascript simple de WebAppers con CSS .

Widget de barra de progreso de carga de archivos Dojo es otra opción que utiliza el marco de Dojo Javascript.

EDITAR: Suponiendo que carga una gran cantidad de imágenes (como un álbum de fotos) y las envía a su script PHP, puede usar javascript para leer los resultados de la publicación y actualizar la barra de progreso según la cantidad de imágenes cargadas / número total de imágenes. Esto tiene el efecto secundario de actualizar solo después de que se haya completado cada publicación. Consulte aquí para obtener información sobre cómo publicar con JS.

Joey Robert
fuente
6
-1 La barra de progreso de Javascript es agradable pero no tiene nada que ver con la carga de archivos hasta donde puedo ver. Y la barra de progreso de carga de Dojo no proporciona ninguna interfaz para PHP. Corríjame si me equivoco, por supuesto.
Pekka
1

Se puede hacer una barra de progreso de php / ajax. (Consulte la biblioteca Html_Ajax en pear). Sin embargo, esto requiere instalar un módulo personalizado en php.

Otros métodos requieren el uso de un iframe, a través del cual php busca ver cuánto del archivo se ha subido. Sin embargo, algunos complementos de los navegadores pueden bloquear este iframe oculto porque a menudo se utilizan iframes ocultos para enviar datos maliciosos a la computadora de un usuario.

Su mejor opción es utilizar algún tipo de barra de progreso flash si no tiene control sobre su servidor.

Ali Lown
fuente
Algunos complementos pueden bloquear iframes, pero ¿navegadores? ¿Puede dar un ejemplo?
ya23
Buscar en Google los términos "carga de archivo php ajax" devuelve 4 de los 5 primeros resultados, todos usando iframes (no estoy seguro si el quinto lo hace (la página no se carga)). Eche un vistazo a los ejemplos de cada uno de los sitios.
Ali Lown
De hecho, usan iframes, pero no mencionen que se puede bloquear en cualquier caso. ¿O me lo he perdido?
ya23
Lo siento, leí mal lo que estaba tratando de preguntar, no, no puedo dar ningún ejemplo de navegadores que bloqueen directamente los iframes, estaba pensando en los complementos que la gente usa con ellos, como noscript, que bloquea los iframes. Texto actualizado en la publicación para referencia futura.
Ali Lown