PHP: Usare la libreria cURL per l’upload di file tramite FTP e la gestione sincrona del risultato

Logo librerie cURLLa libreria cURL è stata scritta da Daniel Stenberg
per la connessione attraverso diversi tipi di protocolli fra i quali FTP, http, https, telnet a server remoti. Di particolare interesse è la possibilità di effettuare l’upload via FTP con l’estensione ftp di PHP. Il test che propongo riguarda l’utilizzo di alcune funzioni di questa libreria per l’invio di un file su un server remoto e la gestione sincrona dei dati inviati attraverso il file.
Più semplicemente, invio un file utilizzando il protocollo FTP, attendo che il file sia arrivato senza errori, e poi effettuo il parsing del suo contentuto lanciando uno script sul server passandogli come parametro POST il nome ed il percorso di destinazione del file stesso.

Per prima cosa bisogna accertarsi che il PHP integri le librerie cURL. L’installazione non sembra essere troppo complessa, vi rimando al manuale PHP nella sezione installazione.
I più fortunati, (come me!) che utilizzano WAMP5 non dovranno far altro che abilitare in Impostazioni PHP -> Estensioni PHP -> php_curl.

La sostanza delle funzioni cURL è tutta in questi pochi step:

  • Inizializzare una sessione usando curl_init()
  • Impostare le opzioni per il trasferimento tramite curl_setopt()
  • Eseguire la sessione usando curl_exec()
  • Terminare la sessione con curl_close()

Vediamo il codice dello script testcurlftp.php che effettua l’upload del file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
// ------- Settings ---------------------------
$local_path = "c:/wamp/www/test/"; //local path of the file to send
$file_name = "test.txt"; //file name
$ftp_user = 'user'; // ftp username
$ftp_pass = 'password'; // ftp password
$ftp_location = "ftp.yoursite.com/httpdocs"; // ftp site destination
$http_path = "/files/"; // relative http path
//server script location:
$server_script_url = "http://yoursite.com/files/testscript.php";
// -------  End Settings ------------------------
$fileToSend = $local_path.$file_name;
$ftp_url = "ftp://".$ftp_user.":".$ftp_pass."@"
            .$ftp_location.$http_path.$file_name;
$errorMsg = '';
// ------- Upload file through FTP ---------------
if (is_file($fileToSend)){
  $ch = curl_init();
  $fp = fopen ($fileToSend, "r");
  // we upload a TXT file
  curl_setopt($ch, CURLOPT_URL, $ftp_url);
  curl_setopt($ch, CURLOPT_UPLOAD, 1);
  curl_setopt($ch, CURLOPT_INFILE, $fp);
  // set size of the file, which isn't _mandatory_ but 
  // helps libcurl to do extra error checking on the upload.
  curl_setopt($ch, CURLOPT_INFILESIZE, filesize($fileToSend));
  $res = curl_exec ($ch);
  $errorMsg = curl_error($ch);
  $errorNumber = curl_errno($ch);
  curl_close ($ch);
  // Run server script with the uploaded file name passed as a 
  // POST parameter 
  if ($errorNumber==0){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $server_script_url);
    //Return a string as the result of curl_exec()
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'fileuploaded='.$http_path.$file_name);
    $res = curl_exec ($ch);
    $errorMsg = curl_error($ch);
    $errorNumber = curl_errno($ch);
    curl_close ($ch);
    echo $res; //DEBUG
  }
  if ($errorNumber>0){
    print 'cURL error: '.$errorMsg." - n.".$errorNumber; // DEBUG
  }
}
else{
  print 'Cannot find file:'.$fileToSend; //DEBUG
}
?>

Questo invece è il codice dello script testscript.php che gira sul server remoto:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$res = "ERRORE";
if (!empty($_POST['fileuploaded'])){
  $filename = $_SERVER['DOCUMENT_ROOT'].$_POST['fileuploaded'];
  if (is_file($filename)){
    $handle = fopen ($filename, "r");
    $res = fread($handle, filesize($filename));
    fclose($handle);
  }
}
print $res;
?>

Se inviamo il file test.txt che contiene:

<p>Prova invio file con librerie <em>cURL</em> PHP</p>

otteniamo:

Prova invio file con librerie cURL PHP

Download:

Potete scaricare gli script qui.

Conclusioni:

Questi due script sono solo un piccolo test che lascia intravedere le enormi potenzialità di queste librerie. Immaginiamo per esempio di dover aggiornare un database remoto mantenendo il controllo degli errori sia sul trasferimento dei dati che sull’esecuzione delle query. Va detto, inoltre che la libreria mette a disposizione due funzioni per la gestione degli errori: curl_error() e curl_errno() attraverso le quali è possibile implementare un sistema avanzato di log della procedura, e infine attraverso la funzione curl_getinfo() è possibile ottenere informazioni sul tempo di trasferimento, la data del documento ricevuto, il content-type dell’oggetto scaricato e numerose altre.
Interessante è anche la possibilità di lanciare lo script dal server locale attraverso una procedura batch, magari schedulata attraverso le operazioni pianificate (per far questo bisogna ricordarsi di caricare il php.ini che integra la libreria cURL attraverso l’uso del parametro -c).
Per maggiori informazioni su questo utilizzo vi rimando al solito manuale PHP sezione: Utilizzo di PHP da linea di comando.

Riferimenti ed approfondimenti:

Questo articolo è stato pubblicato in Informatica e contrassegnato con , , . Aggiungi ai segnalibri il permalink.