FTP upload e download con progress bar in PHP e JQuery

In questo articolo metto a disposizione una semplice classe in PHP che permette di effettuare upload e download di file verso un server FTP, inoltre è in grado di mostrare lo stato di avanzamento dell’operazione con una progress bar in javascript, ma non solo, perchè stampa anche altre informazioni statistiche come il numero di KB trasferiti e quelli totali, la velocità istantanea e quella media e i secondi totali dell’operazione.

Di seguito un rapido esempio per utilizzare subito la classe:

<html>
<head>
  <title>Test FTP</title>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript" src="js/jquery.progressbar.min.js"></script>
</head>
<body>

<?php
require('FTPclient.php');
$ftp = new FTPclient('127.0.0.1','anonymous','anonymous');

$ftp->upload('test_1.pdf');

$ftp->download('test_2.pdf');
?>

</body>
</html>

Spiegazione in breve

Il nocciolo dei metodi che implementano il download e l’upload sono due funzioni di PHP, rispettivamente ftp_nb_get e ftp_nb_fput.
Queste funzioni sono in grado eseguire il download e l’upload in maniera asincrona, quindi permettono al programma di continuare l’esecuzione e compiere altre azioni, in questo caso viene controllato lo stato di avanzamento del trasferimento e aggiornata la progress bar.
Ad esempio per l’upload:

$file_name = 'test.txt';
$fp = fopen($file_name, 'r');
$filesize = filesize($file_name) / 1000;

$conn_id = ftp_connect($host);
$login_result = ftp_login($conn_id, $user, $pass)

$ret = ftp_nb_fput($conn_id, $file_name, $fp, FTP_BINARY);
while ($ret == FTP_MOREDATA)
{
	$curr_kb = (ftell($fp) / 1000);
	$percent = ceil(($curr_kb / $filesize) * 100);

	echo $percent . PHP_EOL;
	ob_flush();
	flush();

	$ret = ftp_nb_continue($conn_id);
}

if ($ret == FTP_FINISHED)
{
	echo "Upload Complete!";
}
else
{
	echo "There was an error uploading the file...";
}

fclose($fp);

Nell’esempio precedente non ho mostrato come viene aggiornata la progress bar, che è un componente javascript scritto da Gary Teo che si basa sulla libreria Jquery.

<html>
<head>
  <title>Test FTP</title>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript" src="js/jquery.progressbar.min.js"></script>
</head>
<body>

<span class="progressBar" id="pg">0</span>

<script type="text/javascript">

// associa il componente ProgressBar allo span con id 'pg'
$("#pg").progressBar();

// imposta la progress bar al 45%
$('#pg').progressBar(45);

</script>

</body>
</html>

Per altri tipi di configurazione di questo componente vi invito a consultare il sito dello sviluppatore.

Sviluppi futuri e miglioramenti

Questa classe è solo una base di partenza per quello che può essere l’obiettivo finale.
Tra le cose che sicuramente vanno migliorate cito la gestione degli errori, che in questo versione è minimale, inoltre i due metodi non permettono di impostare la cartella di origine e di destinazione del file.

Download

Il pacchetto completo è scaricabile QUI

Risorse

http://t.wits.sg/jquery-progress-bar/
http://www.php.net/manual/en/function.ftp-nb-fput.php
http://www.php.net/manual/en/function.ftp-nb-get.php

12 thoughts to “FTP upload e download con progress bar in PHP e JQuery”

  1. Ciao, molto interessante il tuo articolo.

    Provando ad inserirlo in una upload form l’effetto è che finché il file non viene portato sul server (e quindi arrivo al codice che mi prende il file $_FILES[$fileElementName][‘tmp_name’] e fa l’ftp) la pagina rimane immobile e non parte la progressbar.
    Ho visto una soluzione a pagamento che fa partire la progressbar subito dopo il submit. Avresti qualche consiglio da darmi per realizzarlo?

    Grazie, nic.

  2. ciao,
    ho notato un problema simile soltanto utilizzando IE, perchè gestisce il refresh dell’output in maniera diversa dagli altri browser…
    probabilmente la soluzione a pagamento che hai visto si appoggia su flash..o sbaglio?
    cmq non ho una soluzione x questo problema…

  3. Ciao,
    sto modificando il tuo lavoro per far in modo che i file vengano passati attraverso un form e non con un link diretto.
    Per far ciò ho inserito quindi un modulo in cui vado a passare il file da caricare:

    upload($_FILES[‘input-file-file’][‘name’], $_FILES[‘input-file-file’][‘tmp_name’]);
    }
    }
    ?>

    INVIA

    Ho modificato quindi la funzione upload aggiungendo/modificando solo questo:
    public function upload($file_name, $file_temp)
    {
    $fp=@fopen($file_temp,”r”);
    if (!$fp) {
    echo ‘Impossibile aprire il file selezionato’;
    return false;
    }

    Ora arrivo al mio DUBBIO.
    Il locale funziona perfettamente.
    Se carico il file sul server ha un comportamento strano: sembra che lo script faccia 2 volte il lavoro:
    1) prima si copia il file;
    2) viene eseguito l’ftp;

    può essere? si può risolvere in qualche modo il problema?
    Spero di essere stato abbastanza chiaro.
    Ciao
    Federico

  4. Non capisco l’utilità dello script dato che non spieghi come ottenere il path assoluto del file da caricare ma molto comodamente specifichi un file nominato “test.txt”….inutile

  5. Il path assoluto del file da caricare dipende da dove è posizionato!
    Questo script non può sapere a prescindere la directory di tali dile e comunque è una cosa variabile…
    In questo esempio il file “test.txt” si trova nella stessa cartella dello script.

  6. Ottimo tutorial! a quanti vorrebbero trasformarlo in un form-upload, condivido la mia soluzione:

    Upload:

    upload($_FILES[‘file’]);?>

    public function upload($file,$path = ”)
    {
    $name = $file[‘name’];
    $type = $file[‘type’];
    $tmp_name = $file[‘tmp_name’];
    $error = $file[‘error’];
    $size = $file[‘size’];

  7. for downloading the script not working, I getting the following error:

    Downloading file: 0 / -0 KB…
    Speed: 0 KB/s
    0% 0%
    Error downloading file.

  8. Ciao,
    ho seguito più o meno il tuo codice, molto utile.
    Solo una pecca: se si cambia pagina, l’ftp si annulla.
    Non c’è un modo per tenerlo attivo?

    Grazie

Rispondi a Andrea Venturi Annulla risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.