Ti, kteří používají cURL po aktualizacích na 5.6.1, 5.5.17, čelili skutečnosti, že modul cURL přestal fungovat. Problém od té doby nezmizel. I v nejnovější verzi PHP 5.6.4 tento problém přetrvával.

Jak poznáte, že vám cURL funguje?

Vytvořit php soubor a zkopírujte tam:

Otevřete jej ze serveru. Pokud je výstup něco jako:

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

Takže cURL je v pořádku, pokud je to místo toho chyba PHP, pak je problém.

Nejprve samozřejmě zkontrolujte soubor php.ini, najděte tam řádek

Přípona=php_curl.dll

A ujistěte se, že před ním není středník.

Je-li tomu tak a cURL nefunguje, lze provést další test k potvrzení neobvyklé situace. Vytvořte další php soubor s obsahem:

Vyhledejte v prohlížeči cURL, pokud existuje pouze jedna shoda, modul cURL se nenačte:

Apache i PHP přitom fungují jako obvykle.

Tři řešení:

  1. Metoda jedna (ne košer). Pokud máte PHP 5.6.*, tak vezměte verzi PHP 5.6.0, odtud vezměte starý soubor php_curl.dll a nahraďte ho svým novým z verze, například PHP 5.6.4. Pro uživatele s PHP 5.5.17 a vyšší musíte vzít stejný soubor z PHP 5.5.16 a nahradit jej také. Jediným problémem je najít tyto staré verze. Můžete se samozřejmě šťourat v http://windows.php.net/downloads/snaps/php-5.6 , ale osobně jsem tam nenašel to, co jsem potřeboval. A samotné rozhodnutí jaksi není úplně košer.
  2. Druhá metoda (velmi rychlá, ale také ne košer). Zkopírujte soubor libssh2.dll z adresáře PHP do adresáře Apache24bin a restartujte Apache.
  3. Metoda tři (košer – košer lidé tleskají ve stoje). Musíte přidat svůj adresář PHP do PATH. Jak to udělat, je velmi dobře popsáno v oficiální dokumentaci.

Kontrolujeme:

Voila, sekce cURL je na svém místě.

proč tomu tak je? Kde se tento problém vzal? Na tuto otázku neexistuje odpověď, ačkoli mechanismus jejího vzniku již byl popsán.

Zdá se, že problém souvisí se skutečností, že 5.6.1 mělo být vydáno s aktualizovanou knihovnou libcurl 7.38.0. To se ale neví jistě, autoři PHP přikyvují na Apache s tím, že tam jsou nějaké chyby.

Mechanismus problému: pokud není zahrnuta systémová PATH adresář PHP, pak když se služba Apache spustí, nemůže najít novou dll (libssh2.dll), která je závislostí pro php_curl.

Relevantní hlášení chyb:

Závažná chyba: Volání nedefinované funkce curl_multi_init() v ...

Obecně se v PHP vyskytly problémy s cURL, zdá se, že když ne vždy, tak velmi často. V procesu googlování mého problému jsem narazil na vlákna, z nichž některá byla stará více než tucet let.

Navíc googlování přineslo několik dalších závěrů:

Na internetu je dost "návodů pro blbce", ve kterých podrobně i s obrázky vyprávějí, jak odkomentovat řádek extension=php_curl.dll v souboru php.ini.

Na oficiálních stránkách PHP v sekci o instalaci cURL jsou pouze dva návrhy týkající se systému Windows:

Pro práci s tímto modulem v soubory Windows libeay32.dll a ssleay32.dll musí existovat v systému proměnná prostředí CESTA. Nepotřebujete soubor libcurl.dll ze stránky cURL.

Četl jsem je desetkrát. Přepnuto na anglický jazyk a přečtěte si to ještě několikrát v angličtině. Pokaždé jsem víc a víc přesvědčen, že tyhle dvě věty napsala zvířata, nebo někdo jen tak skočil na klávesnici – nechápu jejich význam.

Nechybí ani bláznivé tipy a návody (některé se mi podařilo i vyzkoušet).

Na stránce PHP bug report jsem se již přiblížil k odhalení potřeby zahrnout adresář s PHP do systémové proměnné PATH.

Obecně platí, že pro ty, kteří mají problém s cURL a kteří potřebují „zahrnout adresář s PHP do systémové proměnné PATH“, přejděte na již zmíněný návod http://php.net/manual/ru/faq.installation .php#faq .installation.addtopath . Všechno je tam jednoduché, a co je nejdůležitější, to, co je potřeba udělat, je napsáno lidskou řečí.

Máme: php 5.2.3, Windows XP, Apache 1.3.33
Problém - modul cURL není detekován, pokud je PHP spuštěno z Apache
V php.ini je extension=php_curl.dll bez komentáře, extension_dir je nastaven správně,
libeay32.dll a ssleay32.dll se zkopírují do c:\windows\system32.
Funkce phpinfo() však mezi nainstalovanými moduly cURL neukazuje a při spuštění Apache se do protokolu zapíše:

Spuštění PHP: Nelze načíst dynamickou knihovnu "c:/php/ext/php_curl.dll" - Zadaný modul nebyl nalezen.

Pokud spouštíte php z příkazový řádek, pak skripty obsahující příkazy z cURL fungují dobře, a pokud jsou spuštěny z Apache, poskytují následující:
Závažná chyba: Volání nedefinované funkce: curl_init() - a bez ohledu na to, jak je PHP nainstalováno - jako CGI nebo jako modul.

Na internetu jsem opakovaně narazil na popis tohoto problému - konkrétně na modul cURL, ale řešení, která tam byla navržena, nepomáhají. A už jsem změnil PHP 5.2 na PHP 5.2.3 - stále to nepomohlo.

David Mzareulyan [dokumentace]
Mám jedno php.ini - zkontroloval jsem to prohledáním disku. To, že se používá stejný php.ini, snadno potvrzuje i fakt, že změny v něm provedené ovlivňují jak spouštění skriptů z Apache, tak z příkazové řádky.

Daniil Ivanov [dokumentace] Lepší je vytvořit soubor pomocí volání

a otevřete jej pomocí prohlížeče.
A pak spusťte příkaz php řádek-i | grep ini a zkontrolujte cesty k php.ini tak, jak je php vidí, ne podle přítomnosti souboru na disku.

Daniil Ivanov [dokumentace] Co vypíše php -i? Výchozí binární soubor může hledat konfiguraci jinde, v závislosti na možnostech kompilace. Není to poprvé, co jsem se setkal s tím, že mod_php.dll a php.exe se dívají na různé ini soubory a co funguje v jednom, nefunguje v druhém.

Vasilij Sviridov [dokumentace]
php -i vytvoří následující:

Cesta konfiguračního souboru (php.ini) => C:\WINDOWS
Načtený konfigurační soubor => C:\PHP\php.ini

Přesunutí souboru php.ini do adresáře Situace Windows se nemění.

Daniil Ivanov [dokumentace]
A co zbytek modulů? Například php_mysql??? Spojovací? Nebo je to jen cURL, co je tak ošklivé?

Hmm, taky se mi to nenačte... Na hodně jiné konfiguraci (Apache 2.2 plus PHP 5.1.6 pod Zend Studio). Ale o to nejde. Zajímavou věc ukázal experiment se spouštěním Apache z příkazové řádky (přesněji z FAR). Aniž byste se snažili spojit Kurl - vše začíná v partě. Při pokusu o připojení Kurl zobrazí chybu v ... php5ts.dll.

Ahoj!
Měl jsem podobný problém, dlouho jsem hledal řešení, dej víc nová verze PHP, nakonec našel toto fórum. Tady žádné řešení nebylo, tak jsem to zkoušel dál sám.

Založil jsem si pro sebe zend studio a předtím existovala dřívější verze PHP. Možná jeden z nich nainstaloval své knihovny a zůstaly tam - zastaralé.

Díky za tipy, zvláště ten poslední od "Nehxby". Dostal jsem se do C:\windows\system32 a zjistil jsem, že knihovny libeay32.dll a ssleay32.dll nemají stejnou velikost jako ty původní. Nainstaloval jsem memcached, možná potom. Takže pokud jste přidali chot, v system32 go :)

měl stejný problém, použil příkaz php -i | grep ini
ukázal, že chybí knihovna zlib1.dll
bylo to ve složce s Apache, kopii jsem napsal do složky s PHP
Zopakoval jsem příkaz, ukázalo se, že knihovna zlib.dll nestačí, napsal jsem to do složky Apache a vše fungovalo.
a všechny knihovny byly také php5ts.dll, takže zvažte přítomnost všech potřebných knihoven.

Rozhodl se přidat. Protože jsem se také potýkal s tímto problémem. Na toto fórum jsem narazil přes odkaz na jiném webu. Obecně platí, že všechny navrhované možnosti nejsou nic jiného než berle. podstatou řešení ve Windows. musíte nastavit proměnnou PATH. určení, kde máte PHP. a Hallelujah curl nevyhazuje žádné chyby. jako jiné knihovny...

cURL je speciální nástroj určený k přenosu souborů a dat pomocí syntaxe URL. Tato technologie podporuje mnoho protokolů jako HTTP, FTP, TELNET a mnoho dalších. cURL byl původně navržen jako nástroj příkazového řádku. Naštěstí pro nás je knihovna cURL podporována jazykem PHP programování. V tomto článku se podíváme na některé pokročilé funkce cURL a také se dotkneme praktické využití získané znalosti pomocí PHP.

Proč cURL?

Ve skutečnosti je jich mnoho alternativní způsoby načítání obsahu webové stránky. V mnoha případech, většinou z lenosti, jsem použil simple PHP funkce místo cURL:

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

Tyto funkce však nemají prakticky žádnou flexibilitu a obsahují obrovské množství nedostatků z hlediska zpracování chyb a tak dále. Kromě toho existují určité úkoly, které s těmito standardními funkcemi jednoduše nevyřešíte: interakce s cookies, autentizace, odeslání formuláře, nahrávání souborů a tak dále.

cURL je výkonná knihovna, která podporuje mnoho různých protokolů, možností a poskytuje detailní informace o žádostech o URL.

Základní struktura

  • Inicializace
  • Přiřazení parametrů
  • Provedení a vyzvednutí výsledku
  • Uvolnění paměti

// 1. inicializace $ch = curl_init(); // 2. specifikovat možnosti, včetně url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. získat HTML jako výsledek $output = curl_exec($ch); // 4. uzavření spojení curl_close($ch);

Krok #2 (tj. volání curl_setopt()) bude v tomto článku probrán mnohem více než všechny ostatní kroky, protože. v této fázi se dějí všechny nejzajímavější a nejužitečnější věci, které potřebujete vědět. V cURL existuje velké množství různých možností, které musí být specifikovány, aby bylo možné nakonfigurovat požadavek URL tím nejdůkladnějším způsobem. Nebudeme brát v úvahu celý seznam jako celek, ale zaměříme se pouze na to, co považuji za nezbytné a užitečné pro tuto lekci. Vše ostatní si můžete prozkoumat sami, pokud vás toto téma zajímá.

Kontrola chyb

Kromě toho můžete také použít podmíněné příkazy pro kontrolu, zda byla operace úspěšná:

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

Zde vás žádám, abyste si toho všimli důležitý bod: pro srovnání bychom měli použít "=== false" místo "== false". Pro ty, kteří to neznají, nám to pomůže rozlišit mezi prázdným výsledkem a falešnou booleovskou hodnotou, která bude indikovat chybu.

Příjem informací

Dalším dalším krokem je získat data o cURL požadavku po jeho provedení.

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

Vrácené pole obsahuje následující informace:

  • "url"
  • "typ obsahu"
  • http_code
  • "velikost_hlavičky"
  • "velikost_požadavku"
  • "doba souboru"
  • "ssl_verify_result"
  • "počet_přesměrování"
  • "celkový čas"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • size_download
  • "speed_download"
  • "speed_upload"
  • "délka_obsahu ke stažení"
  • "délka_nahrávaného_obsahu"
  • "starttransfer_time"
  • "čas_přesměrování"

Detekce přesměrování v závislosti na prohlížeči

V tomto prvním příkladu napíšeme kód, který dokáže detekovat přesměrování URL na základě různá nastavení prohlížeč. Některé webové stránky například přesměrovávají prohlížeče mobilní telefon, nebo jakékoli jiné zařízení.

K určení našich odchozích HTTP hlaviček, včetně názvu prohlížeče uživatele a dostupných jazyků, použijeme možnost CURLOPT_HTTPHEADER. Nakonec budeme schopni určit, které stránky nás přesměrovávají na různé adresy URL.

// testovací URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // testování prohlížečů $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 jako Mac OS X; en) AppleWebKit/420+ (KHTML, jako Gecko) verze/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "francouzš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 jako $url) ( echo "URL: $url\n"; foreach ($prohlížeče jako $test_name => $browser) ( $ch = curl_init(); // zadejte url curl_setopt($ch, CURLOPT_URL, $url); // nastavení záhlaví prohlížeče curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"])" ) ); // nepotřebujeme obsah stránky curl_setopt($ch, CURLOPT_NOBODY, 1); // potřebujeme získat hlavičky HTTP curl_setopt($ch, CURLOPT_HEADER, 1); // vrátí výsledky místo výstupu curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // Došlo k přesměrování HTTP? if (preg_match("!Location: (.*)!", $output, $matches) ) ( echo " $test_name: přesměruje na $matches\n"; ) else ( echo "$test_name: žádné přesměrování\n"; ) ) echo "\n\n"; )

Nejprve určíme seznam adres URL stránek, které budeme kontrolovat. Přesněji, potřebujeme adresy těchto stránek. Dále musíme definovat nastavení prohlížeče, abychom mohli otestovat každou z těchto adres URL. Poté použijeme smyčku, ve které projdeme všechny získané výsledky.

Trik, který používáme v tomto příkladu k nastavení nastavení cURL, nám umožní získat nikoli obsah stránky, ale pouze HTTP hlavičky (uložené v $output). Dále můžeme pomocí jednoduchého regulárního výrazu určit, zda byl v přijatých hlavičkách přítomen řetězec „Location:“.

Když spustíte tento kód, měli byste získat něco takového:

Odeslání požadavku POST na konkrétní adresu URL

Při vytváření požadavku GET mohou být přenášená data předána URL prostřednictvím „řetězce dotazu“. Když například vyhledáváte na Googlu, hledané výrazy se nacházejí v adresní řádek nová adresa URL:

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

K simulaci tohoto požadavku nemusíte používat cURL. Pokud vás lenost konečně přemůže, použijte funkci „file_get_contents ()“, abyste získali výsledek.

Jde ale o to, že některé formuláře HTML odesílají požadavky POST. Data těchto formulářů jsou přenášena prostřednictvím těla HTTP požadavku a ne jako v předchozím případě. Pokud jste například vyplnili formulář na fóru a klikli na tlačítko Hledat, bude s největší pravděpodobností odeslán požadavek POST:

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

Můžeme psát PHP skript, který může napodobovat tento druh adresy URL požadavku. Nejprve vytvořte jednoduchý soubor pro přijímání a zobrazování dat POST. Říkejme tomu post_output.php:

Print_r($_POST);

Poté vytvoříme PHP skript pro provedení cURL požadavku:

$url = "http://localhost/post_output.php"; $post_data = array("foo" => "bar", "query" => "Nettuts", "action" => "Odeslat"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // indikuje, že máme požadavek POST curl_setopt($ch, CURLOPT_POST, 1); // přidání proměnných curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $výstup;

Když spustíte tento skript, měli byste získat podobný výsledek:

Požadavek POST byl tedy odeslán skriptu post_output.php, který obratem vydal na výstup superglobální pole $_POST, jehož obsah jsme získali pomocí cURL.

Nahrání souboru

Nejprve vytvořte soubor, abychom jej vytvořili, a odešleme jej do souboru upload_output.php:

Print_r($_FILES);

A zde je kód skriptu, který provádí výše uvedenou funkci:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // soubor k nahrání "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); $output = curl_exec($ch); curl_close($ch); echo $výstup;

Když chcete nahrát soubor, stačí jej nahrát jako obvykle proměnná příspěvku, přičemž před něj přidejte symbol @. Když spustíte napsaný skript, získáte následující výsledek:

Více cURL

Jeden z nejvíce silné stránky cURL je schopnost vytvářet "více" obslužných rutin cURL. To vám umožní otevřít připojení k více adresám URL současně a asynchronně.

V klasické verzi požadavku cURL je provádění skriptu pozastaveno a očekává se dokončení operace požadavku URL, po které může skript pokračovat. Pokud máte v úmyslu pracovat s velkým množstvím URL, bude to poměrně časově náročné, protože v klasickém případě můžete pracovat vždy pouze s jednou URL. Tuto situaci však můžeme napravit pomocí speciálních handlerů.

Podívejme se na příklad kódu, který jsem převzal z php.net:

// vytvořit nějaké cURL zdroje $ch1 = curl_init(); $ch2 = curl_init(); // zadejte URL a další parametry 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); //vytvoří více cURL handler $mh = curl_multi_init(); //přidání více obslužných programů curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $aktivní = null; //provedení do ( $mrc ​​​​= curl_multi_exec($mh, $aktivní); ) 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); ) ) //zavřít curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Myšlenka je, že můžete použít více obslužných programů cURL. Pomocí jednoduché smyčky můžete sledovat, které požadavky ještě nebyly dokončeny.

V tomto příkladu jsou dvě hlavní smyčky. První smyčka do-while volá funkci curl_multi_exec(). Tato funkce je neblokující. Provede se tak rychle, jak jen může, a vrátí stav požadavku. Pokud je vrácená hodnota konstanta 'CURLM_CALL_MULTI_PERFORM', znamená to, že práce ještě nebyla dokončena (např. tento moment hlavičky http jsou odeslány na adresu URL); Proto tuto návratovou hodnotu stále kontrolujeme, dokud nedosáhneme jiného výsledku.

V dalším cyklu zkontrolujeme podmínku, zatímco $active = "true". Je to druhý parametr funkce curl_multi_exec(). Hodnota této proměnné bude "true", pokud bude aktivní jakákoliv z existujících změn. Dále zavoláme funkci curl_multi_select(). Jeho provádění se „blokuje“, pokud existuje alespoň jedno aktivní připojení, dokud není přijata odpověď. Když k tomu dojde, vrátíme se do hlavní smyčky, abychom pokračovali ve vykonávání požadavků.

A nyní aplikujme to, co jsme se naučili, na příkladu, který bude opravdu užitečný pro velké množství lidí.

Kontrola odkazů ve WordPressu

Představte si blog s obrovské množství příspěvky a zprávy, z nichž každá obsahuje odkazy na externí internetové zdroje. Některé z těchto odkazů již mohou být z různých důvodů „mrtvé“. Možná byla stránka smazána nebo stránka vůbec nefunguje.

Vytvoříme skript, který analyzuje všechny odkazy a najde webové stránky, které se nenačítají, a 404 stránek, a pak nám poskytne velmi podrobnou zprávu.

Hned řeknu, že toto není příklad vytvoření pluginu pro WordPress. To je pro nás asi všechno dobré testovací místo.

Pojďme konečně začít. Nejprve musíme načíst všechny odkazy z databáze:

// konfigurace $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // inicializace proměnné $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $aktivní = null; // připojení k MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Nelze se připojit: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Mohl not select db: " . mysql_error()); ) // vybrat všechny publikované příspěvky s odkazy $q = "VYBRAT post_content FROM wp_posts KDE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post "" ; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // načtení odkazů pomocí regulární výrazy if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) (foreach ($se shoduje s $url) ( $tmp = parse_url($url) ; if (in_array($tmp["host"], $excluded_domains)) ( pokračovat; ) $url_list = $url; ) ) ) // odstranění duplicit $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("Žádná adresa URL ke kontrole"); )

Nejprve vygenerujeme konfigurační data pro interakci s databází, poté sepíšeme seznam domén, které se kontroly nezúčastní ($excluded_domains). Definujeme také číslo, které charakterizuje počet maximálních současných připojení, která použijeme v našem skriptu ($max_connections). Poté se připojíme k databázi, vybereme příspěvky, které obsahují odkazy, a shromáždíme je do pole ($url_list).

Následující kód je trochu složitý, takže jej pochopte od začátku do konce:

// 1. vícenásobná obsluha $mh = curl_multi_init(); // 2. přidejte mnoho adres URL pro ($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; } }

Zde se pokusím dát vše do polic. Čísla v seznamu odpovídají číslům v komentáři.

  1. 1. Vytvořte vícenásobnou obsluhu;
  2. 2. Funkci add_url_to_multi_handle() napíšeme o něco později. Při každém zavolání bude zpracována nová adresa URL. Zpočátku přidáme 10 ($max_connections) URL;
  3. 3. Abychom mohli začít, musíme spustit funkci curl_multi_exec(). Dokud vrací CURLM_CALL_MULTI_PERFORM, máme ještě nějakou práci na práci. Potřebujeme to hlavně proto, abychom vytvářeli spojení;
  4. 4. Následuje hlavní smyčka, která se bude provádět, dokud budeme mít alespoň jedno aktivní připojení;
  5. 5. curl_multi_select() zamrzne a čeká na dokončení vyhledávání URL;
  6. 6. Ještě jednou potřebujeme přimět cURL, aby udělal nějakou práci, jmenovitě načetl vrácená data odpovědi;
  7. 7. Zde probíhá ověřování informací. V důsledku požadavku bude vráceno pole;
  8. 8. Vrácené pole obsahuje obsluhu cURL. To je to, co použijeme k načtení informací o konkrétním požadavku cURL;
  9. 9. Pokud byl odkaz mrtvý nebo vypršel časový limit skriptu, neměli bychom žádný hledat http kód A;
  10. 10. Pokud nám odkaz vrátil stránku 404, pak http kód bude obsahovat hodnotu 404;
  11. 11. Jinak máme před sebou funkční odkaz. (Můžete přidat další kontroly na kód chyby 500 atd...);
  12. 12. Dále odstraníme obsluhu cURL, protože ji již nepotřebujeme;
  13. 13. Nyní můžeme přidat další url a spustit vše, o čem jsme mluvili dříve;
  14. 14. V tomto kroku skript ukončí svou práci. Můžeme odstranit vše, co nepotřebujeme, a vygenerovat zprávu;
  15. 15. Na závěr napíšeme funkci, která do handleru přidá url. Statická proměnná $index bude pokaždé inkrementována danou funkci bude voláno.

Použil jsem tento skript na svém blogu (s některými nefunkčními odkazy přidanými záměrně, abych ho otestoval) a získal jsem následující výsledek:

V mém případě skriptu trvalo necelé 2 sekundy, než prošel 40 URL. Zvýšení výkonu je významné při práci s ještě větším počtem adres URL. Pokud otevřete deset připojení současně, skript může běžet desetkrát rychleji.

Pár slov o dalších užitečných možnostech cURL

HTTP ověřování

Pokud má adresa URL ověření HTTP, můžete snadno použít následující skript:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // zadejte uživatelské jméno a heslo curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // pokud je přesměrování povoleno curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // poté uložte naše data do cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

FTP upload

PHP má také knihovnu pro práci s FTP, ale zde vám nic nebrání používat nástroje cURL:

// otevření souboru $soubor = fopen("/cesta/k/souboru", "r"); // url by měla obsahovat následující obsah $url = "ftp://username: [e-mail chráněný]:21/cesta/k/novému/souboru"; $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, velikost souboru("/cesta/k/souboru")); // zadat ASCII mod curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = curl_exec ($ch); curl_close($ch);

Pomocí proxy

Svůj požadavek na adresu URL můžete zadat prostřednictvím serveru proxy:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // zadejte adresu curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // pokud potřebujete zadat uživatelské jméno a heslo curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close($ch);

Zpětná volání

Je také možné určit funkci, která bude spuštěna před dokončením požadavku cURL. Když se například načítá obsah odpovědi, můžete začít používat data, aniž byste čekali na jejich úplné načtení.

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

Taková funkce MUSÍ vrátit délku řetězce, což je požadavek.

Závěr

Dnes jsme se seznámili s tím, jak můžete využít knihovnu cURL pro své vlastní sobecké účely. Doufám, že se vám tento článek líbil.

Děkuji! Měj hezký den!