PHP: una classe client universale che utilizza cURL per interrogare Web service attraverso XML

Webservice e cURL I Web service sono strumenti che permettono di scambiare messaggi fra client e server in una rete distribuita, indipendentemente dal linguaggio di programmazione utilizzato. I più diffusi linguaggi per la programmazione web mettono a disposizioni classi e funzioni per la loro implementazione che avviene utilizzando il protocollo SOAP (Simple Object Access Protocol).

Normalmente l’esposizione delle funzioni server avviene attraverso un documento XML che si chiama WSDL (Web Services Description Language). Secondo quanto descritto nel WSDL associato al servizio è possibile interrogare il server attraverso richieste incapsulate in un documento XML e fatte viaggiare attraverso il protocollo HTTP mediante una richiesta di tipo POST.

Leggi tuttoPHP: una classe client universale che utilizza cURL per interrogare Web service attraverso XML

PHP cURL: una classe per controllare link interrotti, status code e nxdomain in parallelo

PHP cURL e status code
PHP cURL e status code

Questa classe nasce dall’esigenza di revisionare i numerosi bookmarks accumulati in anni di navigazione su Internet. Purtroppo uno degli inconvenienti di Internet è proprio la scarsa affidabilità sulla persistenza dei link. Succede spesso che i link collezionati anni prima non siano più attivi oppure siano stati ridirezionati su altri siti.

Questa classe utilizza le librerie cURL che nelle ultime versioni del PHP, sono state integrate nel pacchetto. Ho utilizzato in particolare la famiglia di comandi curl_multi* in modo da poter evadere richieste multiple parallelamente e velocizzare notevolmente il processo. Oltre a poter verificare le url, che vengono fornite al costruttore della classe come array, per particolari status code o per intere famiglie di status code, è possibile anche verificare che la risposta non sia un cosiddetto hit-nxdomain cioè un server che intercetta un nxdomain e propone un redirect ad una pagina di ricerca di domini dal nome simile. In pratica alcuni DNS (p.e. OpenDNS) in caso di dominio inesistente producono redirect pubblicitari attraverso i loro hit-nxdomain.

Leggi tuttoPHP cURL: una classe per controllare link interrotti, status code e nxdomain in parallelo

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: