cURL este un utilitar din linie de comandă folosit pentru transferul de fişiere ce pot fi accesate printr-un URL. Principalul scop şi utilizare a acestui program este automatizarea transferului de fişiere sau secvenţelor de operaţii, fiind o unealtă excelentă de a simula un client web şi acţiunile pe care le poate întreprinde un utilizator în browser-ul lui. cURL suportă transferul de date folosind mai multe protocoale cum ar fi: HTTP, HTTPS, FTP, FTPS, TFTP, Telnet, SCP precum şi altele.
Pentru ca această unealtă să poată fi folosita în diverse aplicaţii, a fost dezvoltată o librărie numită libcurl care poate fi inglobată în diverse aplicaţii şi care oferă aceeaşi funcţionlitate ca şi utilitarul în sine. Limbajul PHP deţine şi el o astfel de librărie, scrisă de către Daniel Stenberg, şi care oferă conectarea cu diverse servere folosind următoarele protocoale: http, https, ftp, gopher, telnet, dict, file şi ldap. Deasemenea libcurl suportă certificate de securitate, POST si PUT prin HTTP, încărcări de fişiere prin FTP sau din formularele HTTP, proxy-uri, cookie-uri sau autentificări folosind nume de utilizator şi parolă.
Un exemplu de folosire simplă este următorul:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://www.google.com'); curl_exec($ch); curl_close($ch);
PHP are implementate o serie de funcţii pentru lucru cu această librărie. Un algoritm general de funcţionare este descris şi în exemplul de mai sus care nu face altceva decât să returneze acceseze pagina google.com. Astfel, la început am creat o nouă sesiune de cURL folosind funcţia curl_init, şi am stocat-o în variabila $ch. Acesteia i se pot adăuga diverse opţiuni care să personalizeze sesiunea respectivă. În final sesiunea se execută, adică cererea către google.com este făcută, iar la final se eliberează resursa creată.
Într-o sesiune de cURL se pot adăuga mai mulţi parametrii care vor determina comportamentul acesteia. Iată câteva dintre cele mai uzuale opţiuni, care vor fi setate folosind funcţia curl_setopt:
- CURLOPT_URL – reprezintă URL-ul pentru care se crează sesiunea şi cu care se va încerca trimiterea/primirea de date
- CURLOPT_USERAGENT – va seta semnătura pe care o va lăsa accesarea la server
- CURLOPT_HTTPHEADER – reprezintă un vector în care se pot defini header-ele de HTTP care se vor folosi la accesarea serverului
- CURLOPT_REFERER – reprezintă URL-ul de pe care vine cererea curentă, cel care a referit acest nou URL
- CURLOPT_ENCODING – reprezintă tipul de arhivare aplicat transferului curent, de regula gzip
- CURLOPT_RETURNTRANSFER – va face ca funcţia curl_exec să nu afişeze aceste rezultatul sesiunii ci sa-l returneze într-o variabilă.
- CURLOPT_HTTPGET – indică faptul că se modalitatea de transmitere a datelor este HTTP GET; aceasta este modalitatea implicită de transmitere a dateleor, astfel că setarea ei este necesară doar dacă într-o aceeaşi sesiune a fost făcută anterior o conexiune diferită
- CURLOPT_POST – va determina trimiterea unei cereri de tip HTTP POST, cea implicită fiind GET
- CURLOPT_POSTFIELDS – poate fi folosit în cazul unei cereri de tip POST şi aici se vor specifica variabilele pentru POST
- CURLOPT_TIMEOUT – reprezintă numărul de secunde pentru care se va reîncerca o conexiune în caz ca cea iniţială a eşuat
- CURLOPT_PORT – este portul pe care se va face cererea şi este implicit 80 pentru o conexiune folosind HTTP şi 21 folosind FTP
- CURLOPT_PROXY – este numele serverului de proxy prin care se va face conexiunea
- CURLOPT_PROXYUSERPWD – numele de utilizator şi parola pentru acces la serverul proxy, dacă sunte necesare
- CURLOPT_FOLLOWLOCATION – va transmite librăriei de cURL să urmeze un redirect în cazul în care serverul o va dicta
- CURLOPT_SSL_VERIFYPEER – verifică valabilitatea certificatului de securitate în cazul unei conexiui folosind SSL
- CURLOPT_SSL_VERIFYHOST – indică faptul că în cazul unei conexiuni securizate, certificatul SSL trebuie să fie emis pentru host-ul care a fost contactat de catre cURL
- CURLOPT_UPLOAD – va fi folosit în cazul unui upload
- CURLOPT_FRESH_CONNECT – indică faptul că se va folosi o conexiune nouă în loc de cea existentă în cache
- CURLOPT_HTTP_VERSION – indică versiunea protocolului HTTP care va fi folosită pentru comunicare
- CURLOPT_MAXREDIRS – numărul maxim de redirectări pe care conexiunea le va urma
- CURLOPT_COOKIE – reprezintă cookie-urile care vor exista în momentul cererii către server
- CURLOPT_COOKIEFILE – reprezintă un fişier în care sunt stocate unul sau mai multe cookie-uri care vor insoţi cererea către server
- CURLOPT_COOKIEJAR – reprezintă un fişier în care se vor stoca cookie-urile provenite de la server
Pe lângă aceşti parametrii care pot fi aplicaţi asupra cererii, există şi diverşi parametri care pot furniza informaţii referitoare la răspunsul venit din partea serverului în urma executării cererii de către cURL. Acestea pot fi acceste folosind funcţia curl_getinfo:
- CURLINFO_HTTP_CODE – va furniza codul de răspuns al cererii
- CURLINFO_TOTAL_TIME – timpul total afecatat sesiunii
- CURLINFO_EFFECTIVE_URL – reprezintă ultimul URL care a fost folosit in sesiunea cURL
- CURLINFO_REDIRECT_TIME – timpul total afectat redirectărilor dictate de server
- CURLINFO_SIZE_UPLOAD – numărul de bytes încărcaţi către server
- CURLINFO_SIZE_DOWNLOAD – numărul de bytes primitţi de la server
- CURLINFO_CONTENT_TYPE – tipul de conţinut primit de la server; este util pentru a distinge între un conţinut HTML şi unul care în mod normal ar fi oferit către download
O atenţie sporită trebuie avută la aceste opţiuni referitor la versiunea de PHP pe care o folosiţi, întru-cât ele au fost introduse de-a lungul timpului sau chiar recent şi nu pot exista în versiunea pe care o utilizaţi.
Trimitere de POST cu cURL
Vom încerca în cele ce urmeză să oferim câteva exemple de folosire a cURL, pentru a exemplifica puterea de lucru care o poate oferi acesta.
Să presupunem, aşadar, existenţa unui formular de autentificare pe un site care va cere utilizatorului adresa de email cu care acesta s-a înregistrat şi parola lui, după cum urmează:
Putem crea astfel un script care să simuleze o autentificare întocmai precum un utilizator s-ar fi autentificat direct pe site.
$ch = curl_init("http://www.example.ro/post.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "email=blog@inphpwetrust.com&pass=foobar");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION , true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);
Am început prin a crea o nouă sesiune care se va conecta la adresa http://www.example.ro/post.php şi pentru care am stabilit că va fi de tip HTTP POST, prin optiunea CURLOPT_POST, am mai setat o pseudo semnătură a “browser-ului” care se va conecta la server prin opţiunea CURLOPT_USERAGENT ca fiind Mozilla Firefox versiunea 3.0.3, varianta pentru Microsoft Windows XP, am indicat ca orice redirecţionare indicată de către server să fie urmărită şi de cURL prin optiunea CURLOPT_FOLLOWLOCATION, CURLOPT_HEADER indică faptul că nici un header primit ca răspuns nu va fi stocat, iar CURLOPT_RETURNTRANSFER va detemina ca doar corpul mesajului să fie preluat, iar în final după execuţia sesiunii de cURL va fi afişat în browser. Opţiunea CURLOPT_POSTFIELDS este cea mai importantă din aceast exemplu şi este cea care va determina autentificarea efectivă, deci într-un final returnarea unui conţinut care ar putea fi văzut doar de o persoană care s-ar autentifica pe un site. Valorile pentru elementele HTML de tip input email şi pass au fost setate aici, ele fiind credenţialele pe care aplicaţia de pe server va efectua autentificarea. Evident acesta este un exemplu simplu şi uşor de “hack-uit”, în ziua de azi multe din site-uri verifică veridicitatea utilizatorului folosindu-se de mai multe elemente sau afişează o imagine cu nişte caractere de recunoscut care pot fi mai greu sau chiar imposibil de nimerit folosind un script PHP.
Upload prin FTP folosind cURL
Deşi sunt şi alte metode de a încărca un fişier pe un server folosind protocolul FTP, sau simplu pentru a citi conţinutul unui director FTP, chiar şi limbajul PHP deţine niste funcţii de lucru cu FTP, cURL poate fi de ajutor atunci când acestea nu sunt dispobilie sau când se doreşte o mai mare flexibilitate în lucrul cu acest protocol. Următorul exemplu va folosi un handler de fişier creat cu funcţia fopen care va fi pasat parametrului CURLOPT_INFILE.
$fp = fopen('image.jpg', 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'ftp://ftp.domain.com/');
curl_setopt($ch, CURLOPT_USERPWD, "ftpuser:ftppass");
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);
curl_close ($ch);
fclose($fp);