Curl Multithread PHP
6Cu totii stim cat de sweet este sa folosim curl pentru diverse aplicatii web. Curl din PHP este folosit in general la verificari, la indexari, la crawlere si orice alte chestii ce necesita simularea unui client care vrea sursa unei pagini web. Totusi exista o mica problema in aceasta situatie.
Pentru a primi continutul a 10 pagini ce se incarca in 0.5 secunde fiecare (sa spunem) vom avea nevoie de 5 secunde pentru a le descarca. Nu e prea eficient, nu? Pentru asta s-a inventat curl multithread, niste functii oferite de PHP Curl ce ofera posibilitatea de a descarca paginile in paralel, timpul total de descarcare al acestora fiind doar timpul maxim al celei mai lente pagini.
Fanache Remus a publicat un articol despre acest subiect pe care vreau sa-l remarc pentru ca e o chestie mai nestiuta de multi.
< ?php //functia curl de procesare in paralel function curl($nodes, $referer) { // atentie la functia asta daca aveti safe mode on nu functioneaza set_time_limit(0); if(!$referer) $referer = $nodes[0]; $node_count = count($nodes); $curl_arr = array(); $master = curl_multi_init(); //initiem multi curl for($i = 0; $i < $node_count; $i++) { //pentru fiecare nod (link) //cream linkul $curl_arr[$i] = curl_init($nodes[$i]); curl_setopt($curl_arr[$i],CURLOPT_FRESH_CONNECT,true); curl_setopt($curl_arr[$i],CURLOPT_CONNECTTIMEOUT,10); curl_setopt($curl_arr[$i],CURLOPT_RETURNTRANSFER,true); curl_setopt($curl_arr[$i],CURLOPT_REFERER,$referer); curl_setopt($curl_arr[$i],CURLOPT_TIMEOUT,30); //il adaugam la masterul multi-curl curl_multi_add_handle($master, $curl_arr[$i]); } $finalresult = array(); $returnedOrder = array(); do{ //extragem contentul curl_multi_exec($master, $running); $info = curl_multi_info_read($master); if($info['handle']) { $finalresult[] = curl_multi_getcontent($info['handle']); $returnedOrder[] = array_search($info['handle'], $curl_arr, true); curl_multi_remove_handle($master, $info['handle']); curl_close($curl_arr[end($returnedOrder)]); } $previousActive = $running; } while($running > 0); //returnam return array_combine($returnedOrder, $finalresult); curl_multi_close($master); } // specificati adresele paginilor in array $urls = array( 'link1', 'link2' ); curl($urls, null); ?>
Foarte bun acest articol.
util articolul, pacat ca ai un broken link
Am actualizat, acum merge. 🙂
Da… ce sa zic.. Genial…
Si limita?
Daca am 20 de milioane de instante de exemplu? Dupa tine.. crezi ca e o idee buna sa le lanseze pe toate in paralel?
Trebuie sa existe si thread limit 🙂
Spune-mi unde ai auzit de inexistenta unei limite la paralelizare. Mi se pare o chestie de bun simt si clar de inteles ca poti paraleliza atat de multe instante cat te tin motoarele.
Da. Si asta trebuie precizat cel putin. Si eventual oferita o alternativa de cod care contine deja posibilitatea limitarii. Nu e tocmai ok sa astepti ca toti userii sa ruleze 1000 de instante paralele ca sa li se crash-uiasca si dupa aceea sa incerce sa gaseasca singuri o metoda de remediere a problemei. Fiecare in parte, acelasi remediu.