Tí, ktorí používajú cURL po aktualizáciách na 5.6.1, 5.5.17, čelili skutočnosti, že modul cURL prestal fungovať. Odvtedy problém nezmizol. Aj v najnovšej verzii PHP 5.6.4 tento problém pretrvával.

Ako viete, či vám cURL funguje?

Vytvorte php súbor a skopíruj tam:

Otvorte ho zo servera. Ak je výstup niečo ako:

Pole ( => 468736 => 3 => 3997 => 0 => 7.39.0 => x86_64-pc-win32 => OpenSSL/1.0.1j => 1.2.7.3 => Pole ( => dict => súbor => ftp => ftps => gopher => http => https => imap => imaps => ldap => pop3 => pop3s => rtsp => scp => sftp => smtp => smtps => telnet => tftp) )

Takže cURL je v poriadku, ak je to namiesto toho chyba PHP, potom je problém.

Najprv samozrejme skontrolujte súbor php.ini, nájdite tam riadok

Prípona=php_curl.dll

A uistite sa, že pred ním nie je bodkočiarka.

Ak je to tak a cURL nefunguje, je možné vykonať ďalší test na potvrdenie nezvyčajnej situácie. Vytvorte ďalší súbor php s obsahom:

Vyhľadajte v prehliadači cURL, ak existuje iba jedna zhoda, modul cURL sa nenačíta:

Zároveň Apache aj PHP fungujú ako obvykle.

Tri riešenia:

  1. Metóda jedna (nie kóšer). Ak máte PHP 5.6.*, vezmite verziu PHP 5.6.0, odtiaľ vezmite starý súbor php_curl.dll a nahraďte ho novým z verzie, napríklad PHP 5.6.4. Pre tých, ktorí majú PHP 5.5.17 a vyššie, musíte vziať rovnaký súbor z PHP 5.5.16 a nahradiť ho tiež. Jediným problémom je nájsť tieto staré verzie. Môžete sa, samozrejme, pohrabať v http://windows.php.net/downloads/snaps/php-5.6 , no osobne som tam nenašiel to, čo som potreboval. A samotné rozhodnutie akosi nie je celkom kóšer.
  2. Druhý spôsob (veľmi rýchly, ale tiež nie kóšer). Skopírujte súbor libssh2.dll z adresára PHP do adresára Apache24bin a reštartujte Apache.
  3. Metóda tri (kóšer – kóšer ľudia tlieskajú v stoji). Musíte pridať svoj PHP adresár do PATH. Ako to urobiť, je veľmi dobre popísané v oficiálnej dokumentácii.

Kontrolujeme:

Voila, sekcia cURL je na mieste.

prečo je to tak? Kde sa vzal tento problém? Na túto otázku neexistuje odpoveď, hoci mechanizmus jej výskytu už bol popísaný.

Zdá sa, že problém súvisí so skutočnosťou, že 5.6.1 malo byť vydané s aktualizovanou knižnicou libcurl 7.38.0. Ale to nie je isté, autori PHP prikyvujú na Apache s tým, že tam sú nejaké chyby.

Mechanizmus problému: ak nie je zahrnutá systémová PATH PHP adresár, potom keď sa spustí služba Apache, nemôže nájsť novú dll (libssh2.dll), ktorá je závislosťou pre php_curl.

Relevantné hlásenia chýb:

Závažná chyba: Volanie nedefinovanej funkcie curl_multi_init() v ...

Vo všeobecnosti sa v PHP vyskytli problémy s cURL, zdá sa, ak nie vždy, potom veľmi často. V procese googlovania môjho problému som narazil na vlákna, z ktorých niektoré boli staré viac ako tucet rokov.

Okrem toho googlenie poskytlo niekoľko ďalších záverov:

Na internete je dosť "návodov pre debilov", v ktorých podrobne aj s obrázkami hovoria, ako odkomentovať riadok extension=php_curl.dll v súbore php.ini.

Na oficiálnej stránke PHP v časti o inštalácii cURL sú len dva návrhy týkajúce sa systému Windows:

Na prácu s týmto modulom v súbory systému Windows libeay32.dll a ssleay32.dll musia existovať v systéme premenná prostredia PATH. Nepotrebujete súbor libcurl.dll zo stránky cURL.

Čítal som ich desaťkrát. Prepnuté na anglický jazyk a prečítajte si to ešte niekoľkokrát v angličtine. Zakaždým som viac a viac presvedčený, že tieto dve vety napísali zvieratá, alebo niekto len tak skočil na klávesnicu – nerozumiem ich významu.

Je tam aj zopár bláznivých tipov a návodov (niektoré som stihla aj vyskúšať).

Na stránke PHP bug report som sa už priblížil k rozlúšteniu potreby zahrnúť adresár s PHP do systémovej premennej PATH.

Vo všeobecnosti platí, že pre tých, ktorí majú problém s cURL a ktorí potrebujú „zahrnúť adresár s PHP do systémovej premennej PATH“, prejdite na vyššie uvedený pokyn http://php.net/manual/ru/faq.installation .php#faq .installation.addtopath . Všetko je tam jednoduché, a čo je najdôležitejšie, to, čo treba urobiť, je napísané ľudskou rečou.

Máme: php 5.2.3, Windows XP, Apache 1.3.33
Problém - modul cURL nie je detekovaný, ak je PHP spustené z Apache
V php.ini je rozšírenie=php_curl.dll bez komentára, súbor extension_dir je nastavený správne,
libeay32.dll a ssleay32.dll sa skopírujú do c:\windows\system32.
Funkcia phpinfo() však medzi nainštalovanými modulmi cURL nezobrazuje a pri spustení Apache sa do protokolu zapíše:

Spustenie PHP: Nedá sa načítať dynamická knižnica "c:/php/ext/php_curl.dll" - Zadaný modul sa nepodarilo nájsť.

Ak spustíte php z príkazový riadok, potom skripty obsahujúce príkazy z cURL fungujú dobre a ak sú spustené z Apache, poskytujú nasledovné:
Závažná chyba: Volanie nedefinovanej funkcie: curl_init() - a bez ohľadu na to, ako je PHP nainštalované - ako CGI alebo ako modul.

Na internete som opakovane narazil na popis tohto problému - konkrétne pre modul cURL, ale riešenia, ktoré tam boli navrhnuté, nepomáhajú. A už som zmenil PHP 5.2 na PHP 5.2.3 - stále to nepomohlo.

David Mzareulyan [dokument]
Mám jeden php.ini - skontroloval som to prehľadaním disku. Skutočnosť, že sa používa rovnaký php.ini, je tiež ľahko potvrdená skutočnosťou, že zmeny v ňom vykonané ovplyvňujú spustenie skriptov z Apache aj z príkazového riadku.

Daniil Ivanov [dokument] Radšej vytvorte súbor hovorom

a otvorte ho pomocou prehliadača.
A potom spustite príkaz php riadok-i | grep ini a skontrolujte cesty k php.ini tak, ako ich vidí php, nie podľa prítomnosti súboru na disku.

Daniil Ivanov [dokument] Čo vypíše php -i? Predvolený binárny súbor môže hľadať konfiguráciu inde v závislosti od možností kompilácie. Nie je to prvýkrát, čo sa stretávam s tým, že mod_php.dll a php.exe sa pozerajú na rôzne ini súbory a to, čo funguje v jednom, nefunguje v druhom.

Vasilij Sviridov [dokument]
php -i vytvára nasledovné:

Cesta konfiguračného súboru (php.ini) => C:\WINDOWS
Načítaný konfiguračný súbor => C:\PHP\php.ini

Presun súboru php.ini do adresára Situácie Windows nemení.

Daniil Ivanov [dokument]
A čo zvyšok modulov? Napríklad php_mysql??? Pripájate sa? Alebo je to len cURL, čo je také škaredé?

Hmm, ani mne sa to nenačítava... Na celkom inej konfigurácii (Apache 2.2 plus PHP 5.1.6 pod Zend Studio). Ale o to nejde. Experiment so spustením Apache z príkazového riadku (presnejšie z FAR) ukázal niečo zaujímavé. Bez toho, aby ste sa pokúšali spojiť Kurl - všetko začína vo zväzku. Pri pokuse o pripojenie Kurl zobrazí chybu v ... php5ts.dll.

Ahoj!
Mal som podobný problém, dlho som hľadal riešenie, daj viac Nová verzia PHP, nakoniec našiel toto fórum. Tu nebolo žiadne riešenie, tak som to skúšal ďalej sám.

Založil som si zend studio a predtým existovala staršia verzia PHP. Možno jeden z nich nainštaloval svoje knižnice a zostali tam - zastarané.

Ďakujem za tipy, hlavne ten posledný od "Nehxby". Dostal som sa do C:\windows\system32 a zistil som, že knižnice libeay32.dll a ssleay32.dll nemajú rovnakú veľkosť ako pôvodné. Nainštaloval som memcached, možno potom. Takže, ak ste pridali chot, v system32 go :)

mal rovnaký problém, použil som príkaz php -i | grep ini
ukázalo, že knižnica zlib1.dll chýba
bolo to v priečinku s Apache, kópiu som napísal do priečinka s PHP
Zopakoval som príkaz, ukázalo sa, že knižnica zlib.dll nestačí, napísal som to do priečinka Apache a všetko fungovalo.
a všetky knižnice boli tiež php5ts.dll, takže zvážte prítomnosť všetkých potrebných knižníc.

Rozhodol sa pridať. Pretože som tiež čelil tomuto problému. Na toto fórum som narazil cez odkaz na inej stránke. Vo všeobecnosti nie sú všetky navrhované možnosti nič iné ako barle. podstatou riešenia v systéme Windows. musíte nastaviť premennú PATH. špecifikovanie, kde máte PHP. a Hallelujah curl nehádže žiadne chyby. ako iné knižnice...

cURL je špeciálny nástroj, ktorý je určený na prenos súborov a údajov pomocou syntaxe URL. Táto technológia podporuje mnoho protokolov ako HTTP, FTP, TELNET a mnoho ďalších. cURL bol pôvodne navrhnutý ako nástroj príkazového riadku. Našťastie pre nás je knižnica cURL podporovaná jazykom PHP programovanie. V tomto článku sa pozrieme na niektoré pokročilé funkcie cURL, ako aj na dotyk praktické využitie získané znalosti pomocou PHP.

Prečo cURL?

V skutočnosti je ich veľa alternatívne spôsoby načítanie obsahu webovej stránky. V mnohých prípadoch, väčšinou z lenivosti, som použil jednoduchý PHP funkcie namiesto cURL:

$obsah = file_get_contents("http://www.nettuts.com"); // alebo $lines = file("http://www.nettuts.com"); // alebo readfile("http://www.nettuts.com");

Tieto funkcie však nemajú prakticky žiadnu flexibilitu a obsahujú obrovské množstvo nedostatkov z hľadiska spracovania chýb a pod. Okrem toho existujú určité úlohy, ktoré s týmito štandardnými funkciami jednoducho nevyriešite: interakcia so súbormi cookie, autentifikácia, odoslanie formulára, nahrávanie súborov atď.

cURL je výkonná knižnica, ktorá podporuje mnoho rôznych protokolov, možností a služieb detailné informácie o žiadostiach o adresy URL.

Základná štruktúra

  • Inicializácia
  • Priraďovanie parametrov
  • Vykonanie a vyzdvihnutie výsledku
  • Uvoľnenie pamäte

// 1. inicializácia $ch = curl_init(); // 2. špecifikujte možnosti vrátane url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. získajte HTML ako výsledok $output = curl_exec($ch); // 4. zatvorte spojenie curl_close($ch);

Krok č. 2 (t. j. volanie curl_setopt()) bude diskutovaný v tomto článku oveľa viac ako všetky ostatné kroky, pretože. v tejto fáze sa dejú všetky najzaujímavejšie a najužitočnejšie veci, ktoré potrebujete vedieť. V cURL existuje veľké množstvo rôznych možností, ktoré musia byť špecifikované, aby bolo možné nakonfigurovať požiadavku na URL tým najdôkladnejším spôsobom. Nebudeme brať do úvahy celý zoznam ako celok, ale zameriame sa len na to, čo považujem za potrebné a užitočné pre túto lekciu. Všetko ostatné môžete preskúmať sami, ak vás táto téma zaujíma.

Kontrola chýb

Okrem toho môžete použiť aj podmienené príkazy Ak chcete skontrolovať, či bola operácia úspešná:

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

Tu vás žiadam, aby ste si to veľmi všimli dôležitý bod: na porovnanie by sme mali použiť "=== false" namiesto "== false". Pre tých, ktorí nie sú oboznámení, nám to pomôže rozlíšiť medzi prázdnym výsledkom a falošnou boolovskou hodnotou, ktorá bude indikovať chybu.

Prijímanie informácií

Ďalším dodatočným krokom je získanie údajov o požiadavke cURL po jej vykonaní.

// ... curl_exec($ch); $info = curl_getinfo($ch); echo "Vzalo" . $info["total_time"] . " sekundy pre url " . $info["url"]; //...

Vrátené pole obsahuje nasledujúce informácie:

  • "url"
  • "Druh obsahu"
  • http_code
  • "veľkosť_hlavičky"
  • "veľkosť_žiadosti"
  • "čas súboru"
  • "ssl_verify_result"
  • "redirect_count"
  • "celkový čas"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • size_download
  • "speed_download"
  • "speed_upload"
  • "dĺžka_obsahu na stiahnutie"
  • dĺžka_nahrávaného_obsahu
  • "starttransfer_time"
  • "čas_presmerovania"

Detekcia presmerovania v závislosti od prehliadača

V tomto prvom príklade napíšeme kód, ktorý dokáže zistiť presmerovanie adries URL na základe rôzne nastavenia prehliadač. Niektoré webové stránky napríklad presmerujú prehliadače mobilný telefón alebo akékoľvek iné zariadenie.

Na určenie odchádzajúcich hlavičiek HTTP vrátane názvu prehliadača používateľa a dostupných jazykov použijeme možnosť CURLOPT_HTTPHEADER. Nakoniec budeme môcť určiť, ktoré stránky nás presmerujú na rôzne adresy URL.

// testovacia URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // testovanie prehliadačov $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" => pole ("user_agent" => "Mozilla/5.0 (iPhone; U ; CPU ako Mac OS X; en) AppleWebKit/420+ (KHTML, ako Gecko) verzia/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "francúzština" => pole ("user_agent" => "Mozilla/4.0 (kompatibilné; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "jazyk" => "fr,fr-FR;q=0.5")); foreach ($urls ako $url) ( echo "URL: $url\n"; foreach ($browsers ako $test_name => $browser) ( $ch = curl_init(); // špecifikujte url curl_setopt($ch, CURLOPT_URL, $url); // nastavenie hlavičiek prehliadača curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"])" ) ); // nepotrebujeme obsah stránky curl_setopt($ch, CURLOPT_NOBODY, 1); // potrebujeme získať hlavičky HTTP curl_setopt($ch, CURLOPT_HEADER, 1); // vráti výsledky namiesto výstupu curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // Došlo k presmerovaniu HTTP? if (preg_match("!Location: (.*)!", $output, $matches) ) ( echo " $test_name: presmeruje na $zhody\n"; ) else ( echo "$test_name: bez presmerovania\n"; ) ) echo "\n\n"; )

Najprv zadáme zoznam adries URL stránok, ktoré budeme kontrolovať. Presnejšie, potrebujeme adresy týchto stránok. Ďalej musíme definovať nastavenia prehliadača, aby sme mohli otestovať každú z týchto adries URL. Potom použijeme slučku, v ktorej prejdeme všetky získané výsledky.

Trik, ktorý používame v tomto príklade na nastavenie nastavenia cURL, nám umožní získať nie obsah stránky, ale iba HTTP hlavičky (uložené v $output). Ďalej pomocou jednoduchého regulárneho výrazu môžeme určiť, či sa v prijatých hlavičkách nachádza reťazec „Umiestnenie:“.

Keď spustíte tento kód, mali by ste dostať niečo takéto:

Odoslanie požiadavky POST na konkrétnu adresu URL

Pri vytváraní požiadavky GET môžu byť prenášané údaje odovzdané URL prostredníctvom „reťazca dopytu“. Keď napríklad vyhľadávate v službe Google, hľadané výrazy sa nachádzajú v adresný riadok nová adresa URL:

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

Na simuláciu tejto požiadavky nemusíte použiť cURL. Ak vás lenivosť konečne premôže, použite funkciu „file_get_contents ()“, aby ste dosiahli výsledok.

Ide však o to, že niektoré formuláre HTML odosielajú požiadavky POST. Údaje týchto formulárov sa prenášajú cez telo HTTP požiadavky a nie ako v predchádzajúcom prípade. Ak ste napríklad vyplnili formulár na fóre a klikli na tlačidlo vyhľadávania, s najväčšou pravdepodobnosťou sa odošle žiadosť POST:

http://codeigniter.com/forums/do_search/

Môžeme si písať PHP skript, ktorý môže napodobňovať tento druh adresy URL žiadosti. Najprv vytvorte jednoduchý súbor na prijatie a zobrazenie údajov POST. Nazvime to post_output.php:

Print_r($_POST);

Potom vytvoríme PHP skript na vykonanie požiadavky cURL:

$url = "http://localhost/post_output.php"; $post_data = array("foo" => "bar", "query" => "Nettuts", "action" => "Odoslať"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // indikuje, že máme požiadavku POST curl_setopt($ch, CURLOPT_POST, 1); // pridanie premenných curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $výstup;

Keď spustíte tento skript, mali by ste dostať podobný výsledok:

Požiadavka POST bola teda odoslaná skriptu post_output.php, ktorý následne vygeneroval superglobálne pole $_POST, ktorého obsah sme získali pomocou cURL.

Nahranie súboru

Najprv vytvorte súbor, aby ste ho vytvorili, a odošlite ho do súboru upload_output.php:

Print_r($_FILES);

A tu je kód skriptu, ktorý vykonáva vyššie uvedené funkcie:

$url = "http://localhost/upload_output.php"; $post_data = pole ("foo" => "bar", // súbor na nahranie "nahrať" => "@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); $output = curl_exec($ch); curl_close($ch); echo $výstup;

Keď chcete nahrať súbor, stačí ho nahrať ako zvyčajne premenná príspevku, pričom pred ňu pridajte symbol @. Keď spustíte napísaný skript, dostanete nasledujúci výsledok:

Viaceré cURL

Jeden z najviac silné stránky cURL je schopnosť vytvárať "viaceré" obslužné programy cURL. To vám umožní otvoriť pripojenie k viacerým adresám URL súčasne a asynchrónne.

V klasickej verzii požiadavky cURL je vykonávanie skriptu pozastavené a očakáva sa dokončenie operácie žiadosti o adresu URL, po ktorej môže skript pokračovať. Ak máte v úmysle interagovať s veľkým množstvom adries URL, bude to dosť časovo náročné, pretože v klasickom prípade môžete naraz pracovať len s jednou adresou URL. Túto situáciu však môžeme napraviť pomocou špeciálnych handlerov.

Pozrime sa na príklad kódu, ktorý som prevzal z php.net:

// vytvorte nejaké cURL zdroje $ch1 = curl_init(); $ch2 = curl_init(); // špecifikujte URL a ďalšie parametre 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); //vytvor viacnásobnú obsluhu cURL $mh = curl_multi_init(); //pridanie viacerých handlerov curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $aktívny = null; //spustenie do ( $mrc ​​​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc ​​​​== CURLM_OK) ( if (curl_multi_select($mh) != -1) ( do ( $mrc ​​​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) //zavrieť curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Myšlienka je, že môžete použiť viacero obslužných programov cURL. Pomocou jednoduchej slučky môžete sledovať, ktoré požiadavky ešte neboli dokončené.

V tomto príklade sú dve hlavné slučky. Prvá slučka do-while volá funkciu curl_multi_exec(). Táto funkcia je neblokujúca. Vykoná sa čo najrýchlejšie a vráti stav požiadavky. Pokiaľ je vrátená hodnota konštanta 'CURLM_CALL_MULTI_PERFORM', znamená to, že práca ešte nebola dokončená (napr. tento moment hlavičky http sa odosielajú na adresu URL); Preto túto návratovú hodnotu stále kontrolujeme, kým nedosiahneme iný výsledok.

V ďalšom cykle skontrolujeme podmienku, kým $active = "true". Je to druhý parameter funkcie curl_multi_exec(). Hodnota tejto premennej bude „true“, pokiaľ bude aktívna akákoľvek z existujúcich zmien. Ďalej zavoláme funkciu curl_multi_select(). Jeho vykonávanie sa „blokuje“, pokiaľ existuje aspoň jedno aktívne pripojenie, kým nedostane odpoveď. Keď sa to stane, vrátime sa do hlavnej slučky, aby sme pokračovali vo vykonávaní dotazov.

A teraz aplikujme to, čo sme sa naučili, na príklade, ktorý bude naozaj užitočný pre veľké množstvo ľudí.

Kontrola odkazov vo WordPress

Predstavte si blog s obrovské množstvo príspevky a správy, z ktorých každá obsahuje odkazy na externé internetové zdroje. Niektoré z týchto odkazov už môžu byť z rôznych dôvodov „mŕtve“. Možno bola stránka odstránená alebo stránka vôbec nefunguje.

Vytvoríme skript, ktorý analyzuje všetky odkazy a nájde webové stránky, ktoré sa nenačítavajú, a 404 stránok, a potom nám poskytne veľmi podrobnú správu.

Hneď poviem, že toto nie je príklad vytvorenia doplnku pre WordPress. Toto je takmer všetko, čo je pre nás dobrým testovacím priestorom.

Poďme konečne začať. Najprv musíme získať všetky odkazy z databázy:

// konfigurácia $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // inicializácia premennej $url_list = array(); $working_urls = array(); $dead_urls = pole(); $not_found_urls = array(); $aktívny = null; // pripojenie k MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Nedá sa pripojiť: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Mohol by sa pripojiť nevyberať db: " . mysql_error()); ) // vybrať všetky publikované príspevky s odkazmi $q = "VYBERTE obsah_príspevku FROM wp_posts KDE post_content LIKE "%href=%" AND post_status = "publikovať" AND post_type = "príspevok "" ; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // načítanie odkazov pomocou regulárne výrazy if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) (foreach ($zodpovedá ako $url) ( $tmp = parse_url($url) ; if (in_array($tmp["host"], $excluded_domains)) ( pokračovať; ) $url_list = $url; ) ) ) // odstránenie duplikátov $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("Žiadna adresa URL na kontrolu"); )

Najprv vygenerujeme konfiguračné údaje pre interakciu s databázou, potom napíšeme zoznam domén, ktoré sa nezúčastnia kontroly ($excluded_domains). Definujeme tiež číslo, ktoré charakterizuje počet maximálnych súčasných spojení, ktoré použijeme v našom skripte ($max_connections). Potom sa pripojíme k databáze, vyberieme príspevky, ktoré obsahujú odkazy, a zhromažďujeme ich do poľa ($url_list).

Nasledujúci kód je trochu zložitý, takže mu pochopte od začiatku do konca:

// 1. viacnásobná obsluha $mh = curl_multi_init(); // 2. pridajte veľa adries URL pre ($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"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

Tu sa pokúsim dať všetko na police. Čísla v zozname zodpovedajú číslam v komentári.

  1. 1. Vytvorte viacnásobnú obsluhu;
  2. 2. Funkciu add_url_to_multi_handle() napíšeme o niečo neskôr. Pri každom volaní sa spracuje nová adresa URL. Na začiatok pridáme 10 ($max_connections) adries URL;
  3. 3. Aby sme mohli začať, musíme spustiť funkciu curl_multi_exec(). Kým vráti CURLM_CALL_MULTI_PERFORM, stále máme na čom pracovať. Potrebujeme to hlavne na vytváranie spojení;
  4. 4. Nasleduje hlavná slučka, ktorá sa vykoná, pokiaľ máme aspoň jedno aktívne spojenie;
  5. 5. curl_multi_select() zamrzne a čaká na dokončenie vyhľadávania URL;
  6. 6. Opäť potrebujeme získať cURL, aby vykonal nejakú prácu, menovite načítal vrátené dáta odpovede;
  7. 7. Tu sa overujú informácie. V dôsledku požiadavky sa vráti pole;
  8. 8. Vrátené pole obsahuje obsluhu cURL. To je to, čo použijeme na získanie informácií o konkrétnej požiadavke cURL;
  9. 9. Ak bol odkaz mŕtvy alebo vypršal časový limit skriptu, nemali by sme žiadne hľadať http kód a;
  10. 10. Ak nám odkaz vrátil stránku 404, potom kód http bude obsahovať hodnotu 404;
  11. 11. Inak máme pred sebou fungujúci odkaz. (Môžete pridať ďalšie kontroly na kód chyby 500 atď...);
  12. 12. Ďalej odstránime obsluhu cURL, pretože ju už nepotrebujeme;
  13. 13. Teraz môžeme pridať ďalšiu adresu URL a spustiť všetko, o čom sme hovorili predtým;
  14. 14. V tomto kroku skript ukončí svoju prácu. Môžeme odstrániť všetko, čo nepotrebujeme, a vygenerovať správu;
  15. 15. Na záver napíšeme funkciu, ktorá do handleru pridá url. Statická premenná $index bude vždy inkrementovaná danú funkciu bude zavolaný.

Použil som tento skript na svojom blogu (s niektorými nefunkčnými odkazmi pridanými zámerne, aby som ho otestoval) a dostal som nasledujúci výsledok:

V mojom prípade skriptu trvalo necelé 2 sekundy, kým prešiel cez 40 adries URL. Zvýšenie výkonu je významné pri práci s ešte väčším počtom adries URL. Ak otvoríte desať spojení súčasne, skript môže bežať desaťkrát rýchlejšie.

Niekoľko slov o ďalších užitočných možnostiach cURL

HTTP autentifikácia

Ak má adresa URL overenie HTTP, môžete jednoducho použiť nasledujúci skript:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // zadajte meno používateľa a heslo curl_setopt($ch, CURLOPT_USERPWD, "mojepouzivatelske meno:mojeheslo"); // ak je presmerovanie povolené curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // potom uložte naše údaje do cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

Nahrávanie cez FTP

PHP má tiež knižnicu na prácu s FTP, ale tu vám nič nebráni použiť nástroje cURL:

// otvorenie suboru $file = fopen("/cesta/k/suboru", "r"); // adresa URL by mala obsahovať nasledujúci obsah $url = "ftp://username: [e-mail chránený]:21/cesta/k/novemu/suboru"; $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, veľkosť súboru("/cesta/k/súboru")); // špecifikácia ASCII mod curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = curl_exec ($ch); curl_close ($ch);

Použitie proxy

Žiadosť o adresu URL môžete zadať prostredníctvom servera proxy:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // zadajte adresu curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // ak potrebujete zadať používateľské meno a heslo curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close($ch);

Spätné volania

Je tiež možné určiť funkciu, ktorá sa spustí ešte pred dokončením požiadavky cURL. Napríklad, keď sa načítava obsah odpovede, môžete začať používať údaje bez toho, aby ste čakali na ich úplné načítanie.

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

Takáto funkcia MUSÍ vrátiť dĺžku reťazca, čo je požiadavka.

Záver

Dnes sme sa zoznámili s tým, ako môžete použiť knižnicu cURL na svoje sebecké účely. Dúfam, že sa vám tento článok páčil.

Ďakujem! Pekný deň!