Scrierea cererilor HTTP folosind Curl. Efectuarea cererilor GET și POST cu Curl

În această postare, voi arăta exemple despre cum să utilizați cURL, unde este folosit și de ce ar trebui să îl înțelegeți dacă nu ați făcut-o deja.

Voi descrie pe scurt ce este și cu ce se mănâncă:

Guzzle a fost creat pentru a simplifica procesul de trimitere a cererilor HTTP. Adesea folosit pentru a trimite cereri către API si orice in general.

Exemplu real:

Aveți un API pe care l-ați dezvoltat recent și este timpul să începeți să lucrați cu el. Ai putea să-ți scrii propria bibliotecă sau chiar o mini-clasă pentru a lucra cu ea, dar (1) ți-ar lua mult timp și, chiar dacă nu ar fi, atunci cel mai probabil soluția nu ar fi cea mai bună, ( 2) trebuie susținut și îmbunătățit în mod constant. În acest caz, este mai bine să utilizați soluție gata făcută care este suportat comunitate mare iar depozitul Guzzle are deja 12 mii de stele, ceea ce este foarte lăudabil.

Vă puteți întreba: De ce este necesar acest lucru dacă există deja o grămadă de biblioteci?

Guzzle a adunat tot ce este mai bun în sine, l-a făcut și mai bun și acum este cel mai popular biblioteca PHP pentru a lucra cu Solicitare HTTP mi. Este foarte tare, doar uită-te la simplitatea cererii:

// Creează un client cu un URI de bază $client = new GuzzleHttp\Client(["base_uri" => "http://site/"]); // Acum puteți trimite o solicitare la http://bologe.. Guzzle își amintește linkul de bază și acum puteți specifica doar paginile ulterioare pentru comoditate $response = $client->request("GET", "about");

Rece? Îmi place foarte mult.

Documentația lui Guzzle este destul de extinsă, este imposibil să descrii fiecare opțiune, iar asta necesită o postare întreagă, pe care cu siguranță o voi scrie în curând :)

Postfaţă

Dacă aveți întrebări, scrieți-le mai jos la această postare și voi fi bucuros să vă ajut. De asemenea, dacă ai vreo corecție la articol și ai văzut o eroare pe undeva sau vrei să adaugi ceva, o să te ascult cu plăcere.

De ce avem nevoie de PHP CURL?
Pentru a trimite cereri HTTP GET, pur și simplu putem folosi file_get_contents() metodă.

File_get_contents(„http://site”)

Dar trimiterea cererii POST și gestionarea erorilor nu sunt ușor cu file_get_contents().

Trimiterea cererilor HTTP este foarte simplă cu PHP CURL. Trebuie să urmați cei patru pași pentru a trimite cererea.

pasul 1). Inițializați sesiunea CURL

$ch = curl_init();

pasul 2). Furnizați opțiuni pentru sesiunea CURL

Curl_setopt($ch,CURLOPT_URL,"http://site"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); //curl_setopt($ch,CURLOPT_HEADER, true); //dacă vrei antete

CURLOPT_URL-> URL de preluat
CURLOPT_HEADER-> pentru a include antetul/nu
CURLOPT_RETURNTRANSFER-> dacă este setat la adevărat, datele sunt returnate ca șir în loc să le scoată.

pasul 3). Executați sesiunea CURL

$output=curl_exec($ch);

pasul 4).Închideți sesiunea

Curl_close($ch);

Nota: Puteți verifica dacă CURL este activat/nu cu următoarele cod.

If(is_callable("curl_init"))( echo "Activat"; ) else ( echo "Neactivat"; )

1.PHP CURL GET Exemplu

Puteți folosi codul de mai jos pentru a trimite cererea GET.

Funcția httpGet($url) ( $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); // curl_setopt($ch,CURLOPT_HEADER, false); $output= curl_exec($ch); curl_close($ch return $output);

2.PHP CURL POST Exemplu


Puteți folosi codul de mai jos pentru a depune formularul folosind PHP CURL.

Funcția httpPost($url,$params) ( $postData = ""; //creează perechi valori nume separate de & foreach($params as $k => $v) ( $postData .= $k . "=".$ v."&"; $postData = rtrim($postData, "&"); curl_setopt($ch,CURLOPT_URL,$url_setopt($ch,CURLOPT_RETURNTRANSFER); CURLOPT_HEADER, false; curl_setopt($ch, CURLOPT_POST, count($postData));

Cum se utilizează funcția:

$params = array("name" => "Ravishanker Kusuma", "age" => "32", "location" => "India"); echo httpPost("http://site/examples/php/curl-examples/post.php",$params);

3.Trimiteți agent de utilizator aleatoriu în solicitări

Puteți folosi funcția de mai jos pentru a obține agentul utilizator aleatoriu.

Funcția getRandomUserAgent() ( $userAgents=array ("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6", "Mozilla/4.0 (compatibil; MSIE 7.0; Windows NT 5.1)", "Mozilla/4.0 (compatibil; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30.)", "0 (Windows NT 6.0; U; en)", "Mozilla/4.0 (compatibil; MSIE 6.0; Windows NT 5.1; en) Opera 8.50", "Mozilla/4.0 (compatibil; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 ", "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; fr; rv:1.7) Gecko/20040624 Firefox/0.9", "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit /48 (ca Gecko) Safari/48"); $random = rand(0,count($userAgents)-1); return $userAgents[$random]; )

Folosind CURLOPT_USERAGENT, puteți seta șirul User-Agent.

Curl_setopt($ch,CURLOPT_USERAGENT,getRandomUserAgent());

4. Gestionați redirecționările (HTTP 301.302)

Pentru a gestiona redirecționările URL, setați CURLOPT_FOLLOWLOCATION la TRUE. Numărul maxim de redirecționări poate fi controlat folosind CURLOPT_MAXREDIRS.

Curl_setopt($ch,CURLOPT_FOLLOWLOCATION,TRUE); curl_setopt($ch,CURLOPT_MAXREDIRS,2);//doar 2 redirecționări

5.Cum să gestionați erorile CURL

putem folosi metodele curl_errno(),curl_error(), pentru a obține ultimele erori pentru sesiunea curentă.
curl_error($ch)-> returnează eroarea ca șir
curl_errno($ch)-> returnează numărul de eroare
Puteți folosi codul de mai jos pentru a gestiona erorile.

Funcția httpGetWithErros($url) ( $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $output=curl_exec($ch); if($output == = false) ( echo „Numărul erorii:”.curl_errno($ch).”
"; echo "Șir de eroare:".curl_error($ch); ) curl_close($ch); return $output; )

Acest software, constând dintr-o utilitate linie de comandăși biblioteci concepute pentru transferul de date prin diferite protocoale (HTTP, FTP, POP3, IMAP, SMTP și multe altele). Ne vom uita doar la utilitarul de linie de comandă, pe care îl vom scrie „curl” ca nume. Abilitățile dobândite prin utilizarea acestuia facilitează lucrul cu biblioteca libcurl. În plus, ne vom limita la formarea cererilor HTTP: GET și POST.

Informații preliminare

Protocolul HTTP

HTTP este un protocol folosit la schimbul de date între un server web și un program client (cum ar fi un browser). Este format din șiruri de text ASCII trimise de la client la server pentru a solicita o acțiune. Când se primește o cerere, serverul răspunde clientului cu mai multe servicii șiruri de text, iar apoi returnează conținutul solicitat.

Folosind comutatorul -v, puteți vedea exact ce comenzi trimite curl către server. Această cheie face posibilă înțelegerea particularităților interacțiunii dintre curl și serverul web și ajută la depanarea cererii.

URL

URL (Uniform Resource Locator) specifică adresa unei anumite resurse de pe Internet. De exemplu, adresa URL a unei pagini web cURL este scrisă astfel: http://curl.haxx.se.

Forme

Formularele sunt seturi de câmpuri plasate pe o pagină web. Utilizatorul introduce date în aceste câmpuri, apoi dă clic pe butonul „OK” sau „Trimite”, după care datele sunt trimise către server. Serverul primește datele și decide ce să facă în continuare: dacă să caute informații în baza de date, să afișeze adresa introdusă pe o hartă sau să folosească informațiile pentru autentificarea utilizatorului. Desigur, „decide” înseamnă că pe partea de server trebuie să existe un fel de program care primește și procesează datele trimise. Cel mai simplu exemplu: formular de căutare Google.

Referinţă

Ajutor pentru curl poate fi obținut prin tastare

$ - prompt de linie de comandă.

Obține conținutul paginii (GET)

Cea mai simplă și mai comună solicitare HTTP este obținerea conținutului unei anumite adrese URL. Adresa URL se poate referi la o pagină web, o imagine sau un alt fișier. Clientul trimite o cerere GET către server și primește documentul solicitat. Dacă executați comanda

$ curl http://curl.haxx.se

veți obține o pagină web afișată într-o fereastră de terminal (mai precis, în ieșire standard). Pentru a salva această pagină în fișierul curl.html, trebuie să specificați

$ curl http://curl.haxx.se -o "curl.html"

Toate răspunsurile HTTP conțin un set de anteturi care sunt de obicei ascunse. Pentru a vedea aceste anteturi împreună cu documentul în sine, utilizați comutatorul -i.

Trimiteți o solicitare GET dintr-un formular

Formularul de cerere poate fi folosit metoda GET. De exemplu, așa:

Dacă deschideți acest cod într-un browser, veți vedea un formular cu câmp de textși un buton etichetat „OK”. Dacă, de exemplu, introduceți „1990” în formular și faceți clic pe „OK”, browserul va crea o nouă adresă URL, pe care o va urma. Această adresă URL va fi un șir format din adresa URL anterioară și un șir de interogare ca acesta: foo.cgi?year=1990&press=OK . Deci, dacă formularul a fost localizat la adresa www.foo.com/year.html (adresa a fost scoasă „din aer”!), atunci când faceți clic pe butonul „OK” veți fi dus la adresa URL www.foo.com/foo.cgi?year= 1990&press=OK .

Pentru a genera o solicitare GET, introduceți ceea ce era de așteptat din formular:

$ curl „www.foo.com/foo.cgi?year=1990&press=OK”

metoda POST

Metoda GET face ca toate informațiile introduse să fie afișate în bara de adrese browser. Evident, aceasta nu este cea mai bună metodă în cazurile în care trebuie să trimiteți date sensibile sau când cantitatea de informații introduse este foarte mare. Pentru a rezolva această problemă Protocolul HTTP oferă utilizatorului o altă metodă - POST. Cu acesta, clientul trimite date separat de adresa URL și, prin urmare, nu le veți vedea în bara de adrese a browserului.

Formularul care generează cererea POST diferă de cel precedent doar prin metoda de trimitere:

curl va genera o solicitare POST cu aceleași date, după cum urmează:

$ curl -d "year=1990&press=%20OK%20" www.foo.com/foo.cgi

Vă rugăm să rețineți că datele pe care le trimiteți către server trebuie să fie codificate corect. curl nu va face asta pentru tine. De exemplu, dacă doriți ca datele să conțină un spațiu, atunci trebuie să înlocuiți acest spațiu cu %20 etc. Aceasta este una dintre cele mai frecvente erori, ca urmare a căreia datele nu sunt transferate conform așteptărilor.

Încărcarea fișierelor folosind POST

Formularul în care utilizatorul poate încărca un fișier arată cam așa:

Rețineți că Content-Type este setat la multipart/form-data .

Pentru a trimite date către acest formular folosind curl, introduceți:

$ curl -F încărcare = @localfilename -F apăsați = OK [adresa URL a paginii formular]

Câmpuri de formular ascunse

Câmpurile ascunse din formulare sunt una dintre cele mai comune modalități de a transmite informații despre starea unei aplicații HTML. Astfel de câmpuri nu sunt completate, sunt invizibile pentru utilizator, dar sunt transmise în același mod ca și câmpurile obișnuite.

Exemplu de formular cu un câmp vizibil și unul ascuns:

Pentru a trimite o solicitare POST cu curl, nu trebuie să vă faceți griji dacă un câmp este ascuns sau nu - pentru curl, toate câmpurile sunt la fel:

$ curl -d „an=1990&press=OK&person=daniel”[URL]

Cum arată o solicitare POST din interior?

Când completați un formular folosind curl și îl trimiteți la server, probabil că doriți ca cererea POST generată de curl să arate la fel ca și cum ar fi fost făcută folosind un browser.

Cel mai simplu mod de a vă vedea solicitarea POST este următorul:

  1. salvați pagina web cu formularul pe disc;
  2. schimbați metoda în GET;
  3. faceți clic pe butonul „Trimiteți” (puteți modifica și adresa URL la care vor fi trimise datele).

Veți vedea datele atașate la adresa URL și separate prin caractere? , așa cum este de așteptat atunci când utilizați formularele GET.

cURL este un instrument special conceput pentru a transfera fișiere și date folosind sintaxa URL. Această tehnologie acceptă multe protocoale, cum ar fi HTTP, FTP, TELNET și multe altele. cURL a fost conceput inițial pentru a fi un instrument de linie de comandă. Din fericire pentru noi, biblioteca cURL este acceptată de limbaj Programare PHP. În acest articol ne vom uita la unele dintre caracteristicile avansate ale cURL și, de asemenea, vom acoperi aplicare practică cunoștințe dobândite folosind PHP.

De ce cURL?

De fapt, sunt multe moduri alternative mostre de conținut al paginii web. În multe cazuri, în principal din cauza lenei, am folosit PHP simplu funcții în loc de cURL:

$content = file_get_contents("http://www.nettuts.com"); // sau $linii = fisier("http://www.nettuts.com"); // sau readfile ("http://www.nettuts.com");

Cu toate acestea, aceste funcții practic nu au flexibilitate și conțin un număr mare de deficiențe în ceea ce privește gestionarea erorilor etc. În plus, există anumite sarcini pe care pur și simplu nu le poți rezolva cu acestea funcții standard: interacțiune cu cookie-uri, autentificare, trimitere formular, încărcare fișier etc.

cURL este o bibliotecă puternică care acceptă multe protocoale, opțiuni și oferă diferite informatii detaliate despre solicitările URL.

Structura de bază

  • Inițializare
  • Atribuirea parametrilor
  • Rezultatul execuției și preluarea
  • Eliberarea memoriei

// 1. initializare $ch = curl_init(); // 2. specificați parametrii, inclusiv url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. obține HTML ca rezultat $output = curl_exec($ch); // 4. închide conexiunea curl_close($ch);

Pasul #2 (adică apelarea curl_setopt()) va fi discutat mult mai mult în acest articol decât toți ceilalți pași, deoarece În această etapă, se întâmplă toate cele mai interesante și utile lucruri pe care trebuie să le știi. În cURL există un număr mare de opțiuni diferite care trebuie specificate pentru a putea configura solicitarea URL în cel mai atent mod. Nu vom lua în considerare întreaga listă, ci ne vom concentra doar pe ceea ce consider necesar și util pentru această lecție. Puteți studia orice altceva dacă acest subiect vă interesează.

Verificarea erorilor

În plus, puteți utiliza și declarații condiționale pentru a verifica succesul operațiunii:

// ... $ieșire = curl_exec($ch); if ($ieșire === FALSE) ( echo "cURL Error: " . curl_error($ch); ) // ...

Aici vă rog să notați pentru dvs. foarte punct important: Ar trebui să folosim „=== false” pentru comparație în loc de „== false”. Pentru cei care nu cunosc, acest lucru ne va ajuta să distingem între un rezultat gol și o valoare booleană false, ceea ce va indica o eroare.

Obținerea de informații

Un alt pas suplimentar este obținerea datelor despre cererea cURL după ce aceasta a fost executată.

// ... curl_exec($ch); $info = curl_getinfo($ch); ecou „Luat” . $info["total_time"] . „secunde pentru url”. $info["url"]; //...

Matricea returnată conține următoarele informații:

  • "url"
  • „tip_conținut”
  • „http_code”
  • "header_size"
  • „request_size”
  • "filetime"
  • „ssl_verify_result”
  • „redirect_count”
  • „total_time”
  • „namelookup_time”
  • „connect_time”
  • „pretransfer_time”
  • „size_upload”
  • „size_download”
  • „viteză_descărcare”
  • „speed_upload”
  • „download_content_length”
  • „încărcare_conținut_lungime”
  • „starttransfer_time”
  • „redirect_time”

Detectarea redirecționării în funcție de browser

În acest prim exemplu, vom scrie cod care poate detecta redirecționările URL pe baza diverse setari browser. De exemplu, unele site-uri web redirecționează browserele telefon mobil, sau orice alt dispozitiv.

Vom folosi opțiunea CURLOPT_HTTPHEADER pentru a defini antetele noastre HTTP de ieșire, inclusiv numele browserului utilizatorului și limbile disponibile. În cele din urmă, vom putea determina ce site-uri ne redirecționează către adrese URL diferite.

// testează URL-ul $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // testarea browserelor $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5) .6 (.NET CLR 3.5.30729)", "language" => "en-us,en;q=0.5"), "iphone" => array ("user_agent" => "Mozilla/5.0 (iPhone; U); ; CPU ca Mac OS X en) AppleWebKit/420+ (KHTML, ca Gecko) Versiune/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "franceză" => array ("user_agent" => "Mozilla/4.0 (compatibil; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "limba" => "fr,fr-FR;q=0.5"); foreach ($urls ca $url) ( echo "URL: $url\n"; foreach ($browsers ca $test_name => $browser) ( $ch = curl_init(); // specificați adresa URL curl_setopt($ch, CURLOPT_URL , $url); // se specifică antetele pentru browser curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"] )" )); // nu avem nevoie de conținutul paginii curl_setopt($ch, CURLOPT_NOBODY, 1); // trebuie să obținem antete HTTP curl_setopt($ch, CURLOPT_HEADER, 1); // returnăm rezultate în loc de ieșire curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); , $matches) ( echo " $test_name: redirecționează către $matches\n"; ) else ( echo "$test_name: no redirection\n"; ) ) echo "\n\n" )

Mai întâi, specificăm o listă de adrese URL ale site-urilor pe care le vom verifica. Mai exact, vom avea nevoie de adresele acestor site-uri. În continuare, trebuie să definim setările browserului pentru a testa fiecare dintre aceste adrese URL. După aceasta, vom folosi o buclă în care vom parcurge toate rezultatele obținute.

Trucul pe care îl folosim în acest exemplu pentru a seta setările cURL ne va permite să obținem nu conținutul paginii, ci doar anteturile HTTP (stocate în $output). Apoi, folosind o regex simplă, putem determina dacă șirul „Locație:” a fost prezent în anteturile primite.

Când rulați acest cod, ar trebui să obțineți ceva de genul acesta:

Crearea unei cereri POST la o anumită adresă URL

Când se formează o solicitare GET, datele transmise pot fi transmise la adresa URL printr-un „șir de interogare”. De exemplu, când efectuați o căutare pe Google, termenul de căutare este plasat în bara de adrese a noii adrese URL:

Http://www.google.com/search?q=ruseller

Nu trebuie să utilizați cURL pentru a simula această solicitare. Dacă lenea te învinge complet, folosește funcția „file_get_contents()” pentru a obține rezultatul.

Dar chestia este că unele formulare HTML trimit solicitări POST. Datele acestor formulare sunt transportate prin corpul cererii HTTP, și nu ca în cazul precedent. De exemplu, dacă ați completat un formular pe un forum și ați făcut clic pe butonul de căutare, cel mai probabil va fi făcută o solicitare POST:

Http://codeigniter.com/forums/do_search/

Putem scrie Script PHP, care poate simula acest tip de adresă URL de solicitare. Mai întâi să creăm un fișier simplu de acceptat și afișat date POST. Să-i spunem post_output.php:

Print_r($_POST);

Apoi creăm un script PHP pentru a face cererea cURL:

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "Submit"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // indică faptul că avem o cerere POST curl_setopt($ch, CURLOPT_POST, 1); // adaugă variabile curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $ieșire = curl_exec($ch); curl_close($ch); echo $ieșire;

Când rulați acest script, ar trebui să obțineți un rezultat ca acesta:

Astfel, cererea POST a fost trimisă către scriptul post_output.php, care la rândul său iese matrice superglobală$_POST, al cărui conținut l-am obținut folosind cURL.

Încărcarea unui fișier

Mai întâi, să creăm un fișier pentru a-l genera și a-l trimite în fișierul upload_output.php:

Print_r($_FILES);

Și iată codul de script care realizează funcționalitatea de mai sus:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // fișier pentru a încărca "upload" => "@C:/wamp/www/test.zip"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $ieșire = curl_exec($ch); curl_close($ch); echo $ieșire;

Când doriți să încărcați un fișier, tot ce trebuie să faceți este să îl transmiteți ca o variabilă post normală, precedată de simbolul @. Când rulați scriptul scris, veți obține următorul rezultat:

CURL multiple

Unul dintre cele mai mari puncte forte ale cURL este capacitatea de a crea „mai multe” handlere cURL. Acest lucru vă permite să deschideți o conexiune la mai multe adrese URL simultan și asincron.

În versiunea clasică a cererii cURL, execuția scriptului este suspendată și așteaptă finalizarea operației de solicitare URL, după care scriptul poate continua. Dacă intenționați să interacționați cu o mulțime de adrese URL, aceasta va duce la o investiție destul de semnificativă de timp, deoarece în versiunea clasică puteți lucra doar cu o singură adresă URL la un moment dat. Cu toate acestea, îl putem repara această situație, folosind manipulari speciali.

Să ne uităm la exemplul de cod pe care l-am luat de la php.net:

// creează mai multe resurse cURL $ch1 = curl_init(); $ch2 = curl_init(); // specificați URL-ul și alți parametri curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); //creez un handler cURL multiplu $mh = curl_multi_init(); //adăugați mai mulți handlere curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $activ = nul; //execuți do ($mrc ​​= curl_multi_exec($mh, $activ); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($activ && $mrc ​​​​== CURLM_OK) ( dacă (curl_multi_select($mh) != -1) ( do ( $mrc ​​​​= curl_multi_exec($mh, $activ); ) while ($mrc == CURLM_CALL_MULTI_PERFORM) ) //închidere curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Ideea este că puteți utiliza mai mulți handlere cURL. Folosind o buclă simplă, puteți urmări ce solicitări nu au fost încă finalizate.

Există două bucle principale în acest exemplu. Primul bucla do-while apelează funcția curl_multi_exec(). Această funcție nu este blocabilă. Acesta rulează cât de repede poate și returnează starea cererii. Atâta timp cât valoarea returnată este constanta „CURLM_CALL_MULTI_PERFORM”, aceasta înseamnă că lucrarea nu a fost încă finalizată (de exemplu, se trimite în prezent antetele httpîn URL); De aceea continuăm să verificăm această valoare returnată până când obținem un rezultat diferit.

În bucla următoare verificăm condiția în timp ce variabila $activ = „adevărat”. Este al doilea parametru al funcției curl_multi_exec(). Valoarea acestei variabile va fi „adevărată” atâta timp cât oricare dintre modificările existente este activă. Apoi apelăm funcția curl_multi_select(). Execuția sa este „blocata” în timp ce există cel puțin unul conexiune activă, până la primirea unui răspuns. Când se întâmplă acest lucru, ne întoarcem la bucla principală pentru a continua să executăm interogări.

Acum să aplicăm ceea ce am învățat la un exemplu pentru care va fi cu adevărat util cantitate mare oameni.

Verificarea linkurilor în WordPress

Imaginați-vă un blog cu o sumă imensă postări și mesaje, fiecare dintre acestea conținând link-uri către resurse externe de internet. Unele dintre aceste link-uri ar putea fi deja moarte din diverse motive. Este posibil ca pagina să fi fost ștearsă sau este posibil ca site-ul să nu funcționeze deloc.

Vom crea un script care va analiza toate linkurile și va găsi site-uri web care nu se încarcă și 404 pagini, apoi ne va furniza un raport detaliat.

Permiteți-mi să spun imediat că acesta nu este un exemplu de creare a unui plugin pentru WordPress. Acesta este un teren de testare absolut bun pentru testele noastre.

Să începem în sfârșit. Mai întâi trebuie să preluăm toate linkurile din baza de date:

// configurare $db_host = "localhost"; $db_user = „rădăcină”; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // inițializarea variabilelor $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $activ = nul; // se conectează la MySQL dacă (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Nu s-a putut conecta: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Poate not select db: " . mysql_error()); ) // selectează toate postările publicate cu link-uri $q = "SELECTează post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post"" ; $r = mysql_query($q) sau die(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // preia link-uri folosind expresii regulate if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $potriviri)) ( foreach ($potrivește ca $url) ( $tmp = parse_url($url) ; if (in_array($tmp["gazdă"], $excluded_domains)) (continuare; ) $url_list = $url) ) // eliminați duplicatele $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("Fără URL de verificat"); )

Mai întâi, generăm date de configurare pentru interacțiunea cu baza de date, apoi scriem o listă de domenii care nu vor participa la verificare ($excluded_domains). De asemenea, definim un număr care caracterizează numărul de maxim conexiuni simultane, pe care îl vom folosi în scriptul nostru ($max_connections). Apoi ne alăturăm bazei de date, selectăm postările care conțin link-uri și le acumulăm într-o matrice ($url_list).

Următorul cod este puțin complicat, așa că parcurgeți-l de la început până la sfârșit:

// 1. handler multiplu $mh = curl_multi_init(); // 2. adăugați un set de adrese URL pentru ($i = 0; $i< $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте acest apel curl_close($mhinfo[„mâner”]);

// 13. adăugați o nouă adresă URL și continuați să lucrați dacă (add_url_to_multi_handle($mh, $url_list)) ( do ( $mrc ​​​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) ) ) // 14. completare curl_multi_close($mh); echo "==Adrese URL moarte==\n"; echo implode("\n",$dead_urls) . „\n\n”; echo „==404 URL-uri==\n”; echo implode("\n",$not_found_urls) . „\n\n”; echo "==Adrese URL de lucru==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) ( static $index = 0; // dacă avem mai multe URL-uri care trebuie preluate dacă ($url_list[$index]) ( // new curl handler $ch = curl_init(); // specifica url curl_setopt($ch, CURLOPT_URL, $url_setopt($ch, CURLOPT_RETURNTRANSFER, 1 curl_setopt, CURLOPT_FOLLOWLOCATION, 1 ($ch, CURL); $mh, $ch // mergeți la următoarea url $index++ return true ( // adăugarea de noi URL-uri este finalizată; ) )

  1. Aici voi încerca să explic totul în detaliu. Numerele din listă corespund numerelor din comentariu.
  2. 1. Creați un handler multiplu;
  3. 2. Vom scrie funcția add_url_to_multi_handle() puțin mai târziu. De fiecare dată când este apelat, va începe procesarea unei noi adrese URL. Inițial, adăugăm 10 ($max_connections) URL-uri;
  4. 3. Pentru a începe, trebuie să rulăm funcția curl_multi_exec(). Atâta timp cât returnează CURLM_CALL_MULTI_PERFORM, mai avem ceva de făcut. Avem nevoie de asta în principal pentru a crea conexiuni;
  5. 4. Urmează bucla principală, care va rula atâta timp cât avem cel puțin o conexiune activă;
  6. 5. curl_multi_select() se blochează așteptând finalizarea căutării URL;
  7. 6. Încă o dată, trebuie să facem cURL să lucreze, și anume să preluăm datele răspunsului returnat;
  8. 7. Informațiile sunt verificate aici. Ca urmare a executării cererii, va fi returnată o matrice;
  9. 9. Dacă linkul a fost mort sau scriptul a expirat, atunci nu ar trebui să căutăm niciun cod http;
  10. 10. Dacă linkul ne-a returnat o pagină 404, atunci codul http va conține valoarea 404;
  11. 11. B altfel, avem o legătură de lucru în fața noastră. (Puteți adăuga verificări suplimentare la codul de eroare 500, etc...);
  12. 12. În continuare eliminăm handlerul cURL pentru că nu mai avem nevoie de el;
  13. 13. Acum putem adăuga o altă adresă URL și rula tot ce am vorbit înainte;
  14. 14. La acest pas, scriptul își finalizează munca. Putem elimina tot ce nu avem nevoie și putem genera un raport;
  15. 15. În cele din urmă, vom scrie o funcție care va adăuga url la handler. Variabila statică $index va fi incrementată de fiecare dată când această funcție este apelată.

Am folosit acest script pe blogul meu (cu câteva link-uri rupte pe care le-am adăugat intenționat pentru a-l testa) și am obținut următorul rezultat:

În cazul meu, scriptul a durat puțin mai puțin de 2 secunde pentru a se accesa cu crawlere prin 40 de adrese URL. Creșterea productivității este semnificativă atunci când lucrați cu mai mulți un număr mare adrese URL. Dacă deschideți zece conexiuni în același timp, scriptul se poate executa de zece ori mai repede.

Câteva cuvinte despre alte opțiuni utile de cURL

Autentificare HTTP

Dacă este pornit adresa URL Dacă aveți autentificare HTTP, puteți utiliza cu ușurință următorul script:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // specificam numele de utilizator si parola curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // dacă redirecționarea este permisă curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // apoi salvăm datele noastre în cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $ieșire = curl_exec($ch); curl_close($ch);

Încărcare FTP

PHP are, de asemenea, o bibliotecă pentru lucrul cu FTP, dar nimic nu vă împiedică să utilizați instrumentele cURL aici:

// deschide fisierul $fisier = fopen("/cale/la/fisier", "r"); // URL-ul ar trebui să conțină următorul conținut $url = "ftp://nume utilizator: [email protected]:21/path/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, file size("/path/to/file"); ); curl_close($ch);

Folosind Proxy

Puteți efectua solicitarea URL printr-un proxy:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // specifica adresa curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // dacă trebuie să furnizați un nume de utilizator și o parolă curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $ieșire = curl_exec($ch); curl_close($ch);

Funcții de apel invers

De asemenea, este posibil să specificați o funcție care va fi declanșată înainte de finalizare cURL funcționează cerere. De exemplu, în timp ce conținutul răspunsului se încarcă, puteți începe să utilizați datele fără a aștepta să se încarce complet.

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"funcție_progres"); curl_exec($ch); curl_close($ch); function progress_function($ch,$str) ( echo $str; return strlen($str); )

O funcție ca aceasta TREBUIE să returneze lungimea șirului, ceea ce este o cerință.

Concluzie

Astăzi am învățat cum puteți utiliza biblioteca cURL în dvs în scopuri egoiste. Sper că v-a plăcut acest articol.

Multumesc! O zi plăcută!

  • Serghei Savenkov

    un fel de recenzie „scurtă”... de parcă s-ar grăbi undeva