Curl init php ei toimi. Hiotaan taitojamme työskennellä cURL:n kanssa. Muutama sana muista hyödyllisistä cURL-vaihtoehdoista

Ne, jotka käyttävät cURL-osoitetta, huomasivat 5.6.1- ja 5.5.17-päivitysten jälkeen sen tosiasian, että cURL-moduuli lakkasi toimimasta. Ongelma ei ole poistunut sen jälkeen. Tämä ongelma jatkuu myös PHP 5.6.4:n nykyisessä versiossa.

Mistä tiedät, toimiiko cURL sinulle?

Luo php-tiedosto ja kopioi siihen:

Avaa se palvelimelta. Jos tulos on jotain tällaista:

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

Tämä tarkoittaa, että cURL on hyvä, jos sen sijaan on PHP-virhe, on ongelma.

Ensin tietysti tarkista php.ini-tiedosto, etsi rivi sieltä

Extension=php_curl.dll

Ja varmista, ettei sen edessä ole puolipistettä.

Jos kaikki on niin, mutta cURL ei toimi, voit suorittaa toisen testin varmistaaksesi, että tilanne on epätavallinen. Luo toinen php-tiedosto sisällöllä:

Hae cURL-osoitetta selaimesta; jos vastaa vain yksi, cURL-moduulia ei ladata:

Samaan aikaan sekä Apache että PHP toimivat normaalisti.

Ratkaisuja on kolme:

  1. Ensimmäinen menetelmä (ei kosher). Jos sinulla on PHP 5.6.*, ota versio PHP 5.6.0, sieltä vanha tiedosto php_curl.dll ja korvaa se uudella versiollasi, esimerkiksi PHP 5.6.4. Niille, joilla on PHP 5.5.17 tai uudempi, sinun on otettava sama tiedosto PHP 5.5.16:sta ja korvattava se. On vain yksi ongelma - näiden vanhojen versioiden löytäminen. Voit tietysti kurkata osoitteessa http://windows.php.net/downloads/snaps/php-5.6, mutta henkilökohtaisesti en löytänyt sieltä tarvitsemaani. Ja itse päätös ei ole jotenkin täysin kosher.
  2. Menetelmä kaksi (erittäin nopea, mutta ei myöskään kosher). Kopioi PHP-hakemistosta libssh2.dll-tiedosto Apache24bin-hakemistoon ja käynnistä Apache uudelleen.
  3. Menetelmä kolme (kosher - kosher ihmiset taputtavat seisoessaan). Sinun on lisättävä PHP-hakemistosi PATH:iin. Kuinka tämä tehdään, on kuvattu erittäin hyvin virallisessa dokumentaatiossa.

Tarkistamme:

Voila, cURL-osio on paikallaan.

Miksi niin? Mistä tämä ongelma tuli? Tähän kysymykseen ei ole vastausta, vaikka sen esiintymismekanismi on jo kuvattu.

Ongelma näyttää liittyvän siihen, että 5.6.1 olisi pitänyt julkaista päivitetyn libcurl 7.38.0:n kanssa. Mutta tätä ei tiedetä varmasti; PHP-kirjoittajat viittaavat Apacheen sanoen, että siellä on joitain virheitä.

Miten ongelma ilmenee: Jos järjestelmän PATH ei sisällä PHP-hakemistoa, Apache-palvelu ei löydä uutta dll-tiedostoa (libssh2.dll), joka on php_curl-riippuvuus, kun se käynnistyy.

Aiheeseen liittyvät virheraportit:

Vakava virhe: Kutsu määrittelemättömään funktioon curl_multi_init() kohteessa...

Yleisesti ottaen cURL:n kanssa näytti olevan ongelmia PHP:ssä, jos ei aina, niin hyvin usein. Googlaillessani ongelmaani törmäsin ketjuihin, joista osa oli yli kymmenen vuotta vanhoja.

Lisäksi googlaamalla saatiin useita muita johtopäätöksiä:

Internetissä on tarpeeksi "ohjeita idiooteille", jotka kertovat yksityiskohtaisesti kuvien kanssa, kuinka php.ini-tiedoston rivin extension=php_curl.dll kommentit poistetaan.

Virallisen PHP-sivuston cURL-asennusosiossa on vain kaksi Windows-järjestelmää koskevaa ehdotusta:

Työskennelläksesi tämän moduulin kanssa Windows-tiedostoja libeay32.dll ja ssleay32.dll on oltava järjestelmän PATH-ympäristömuuttujassa. Et tarvitse libcurl.dll-tiedostoa cURL-sivustosta.

Olen lukenut ne kymmenkunta kertaa. Vaihdettu Englannin kieli ja lue se vielä useita kertoja englanniksi. Joka kerta olen yhä vakuuttuneempi siitä, että nämä kaksi lausetta ovat eläinten kirjoittamia tai että joku vain hyppäsi peppunsa näppäimistölle - en ymmärrä niiden merkitystä.

Siellä on myös hulluja vinkkejä ja ohjeita (joitakin onnistuin kokeilemaan).

PHP-virheraportointisivustolla olen jo lähellä selvittämään, mitä järjestelmän PATH-muuttujaan on sisällytettävä, jotta hakemisto sisällytetään PHP:n kanssa.

Yleensä niille, joilla on ongelmia cURL-osoitteen kanssa ja joiden on "sisällytettävä PHP-hakemisto järjestelmän PATH-muuttujaan", siirry yllä mainittuihin ohjeisiin http://php.net/manual/ru/faq.installation .php#faq .installation.addtopath . Siellä kaikki on yksinkertaista, ja mikä tärkeintä, ihmiskielellä on kirjoitettu, mitä on tehtävä.

cURL on erikoistyökalu, joka on suunniteltu siirtämään tiedostoja ja tietoja URL-syntaksin avulla. Tämä tekniikka tukee monia protokollia, kuten HTTP, FTP, TELNET ja monia muita. cURL oli alun perin suunniteltu työkaluksi komentorivi. Onneksi kieli tukee cURL-kirjastoa PHP ohjelmointi. Tässä artikkelissa tarkastelemme joitain cURL:n edistyneitä toimintoja ja käsittelemme myös hankitun tiedon käytännön soveltamista PHP:n avulla.

Miksi cURL?

Itse asiassa on olemassa useita vaihtoehtoisia tapoja kokeilla verkkosivujen sisältöä. Monissa tapauksissa, lähinnä laiskuuden vuoksi, käytin yksinkertaista PHP toiminnot cURL:n sijaan:

$sisältö = file_get_contents("http://www.nettuts.com"); // tai $linjat = tiedosto("http://www.nettuts.com"); // tai readfile("http://www.nettuts.com");

Näillä toiminnoilla ei kuitenkaan ole käytännössä mitään joustavuutta, ja niissä on valtava määrä puutteita virheiden käsittelyssä jne. Lisäksi on tiettyjä tehtäviä, joita et yksinkertaisesti voi ratkaista näillä vakiotoiminnot: vuorovaikutus evästeiden kanssa, todennus, lomakkeen lähettäminen, tiedostojen lataus jne.

cURL on tehokas kirjasto, joka tukee monia erilaisia ​​protokollia, vaihtoehtoja ja tarjoaa yksityiskohtaista tietoa URL-pyynnöistä.

Perusrakenne

  • Alustus
  • Parametrien antaminen
  • Toteutus ja hakutulos
  • Vapauttaa muistia

// 1. alustus $ch = curl_init(); // 2. määritä parametrit, mukaan lukien url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. saa tulokseksi HTML:n $output = curl_exec($ch); // 4. sulje yhteys curl_close($ch);

Vaihe 2 (eli kutsuminen curl_setopt()) käsitellään tässä artikkelissa paljon enemmän kuin kaikkia muita vaiheita, koska Tässä vaiheessa tapahtuu kaikki mielenkiintoisimmat ja hyödyllisimmät asiat, jotka sinun on tiedettävä. cURL:ssä on valtava määrä erilaisia ​​vaihtoehtoja, jotka on määritettävä, jotta URL-pyyntö voidaan määrittää huolellisimmalla tavalla. Emme käsittele koko luetteloa, vaan keskitymme vain siihen, mitä pidän tarpeellisena ja hyödyllisenä tässä oppitunnissa. Voit opiskella kaikkea muuta itse, jos tämä aihe kiinnostaa sinua.

Virheen tarkistus

Lisäksi voit myös käyttää ehdolliset lausunnot tarkistaaksesi toiminnan onnistumisen:

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

Tässä pyydän teitä huomioimaan erittäin tärkeän asian: meidän on käytettävä "=== false" vertailuun "== false" sijaan. Niille, jotka eivät ole perillä, tämä auttaa meitä erottamaan tyhjän tuloksen loogisen arvon false, mikä osoittaa virheen.

Tietojen vastaanottaminen

Toinen lisävaihe on hankkia tietoja cURL-pyynnöstä sen suorittamisen jälkeen.

// ... curl_exec($ch); $info = curl_getinfo($ch); echo "Oti". $info["total_time"] . "sekuntia url:lle". $info["url"]; //…

Palautettu taulukko sisältää seuraavat tiedot:

  • "url"
  • "sisältötyyppi"
  • "http_koodi"
  • "header_size"
  • "request_size"
  • "tiedostoaika"
  • "ssl_verify_result"
  • "uudelleenohjausmäärä"
  • "koko_aika"
  • "namelookup_time"
  • "yhteysaika"
  • "pretransfer_time"
  • "size_upload"
  • "size_download"
  • "nopeus_lataus"
  • "speed_upload"
  • "lataussisällön_pituus"
  • "upload_content_length"
  • "starttransfer_time"
  • "uudelleenohjausaika"

Uudelleenohjauksen tunnistus selaimesta riippuen

Tässä ensimmäisessä esimerkissä kirjoitamme koodin, joka pystyy havaitsemaan URL-uudelleenohjaukset, perustuu eri selaimen asetuksiin. Esimerkiksi jotkut verkkosivustot uudelleenohjaavat selaimia kännykkä, tai mikä tahansa muu laite.

Aiomme käyttää CURLOPT_HTTPHEADER-vaihtoehtoa lähtevien HTTP-otsikoidemme määrittämiseen, mukaan lukien käyttäjän selaimen nimi ja käytettävissä olevat kielet. Lopulta voimme määrittää, mitkä sivustot uudelleenohjaavat meidät eri URL-osoitteisiin.

// testaa URL-osoite $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // selaimien testaus $selaimet = 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 kuten Mac OS X; fi) AppleWebKit/420+ (KHTML, kuten Gecko) Version/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "french" => array ("user_agent" => "Mozilla/4.0 (yhteensopiva; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "kieli" => "fr,fr-FR;q=0.5")); foreach ($urls muodossa $url) ( echo "URL: $url\n"; foreach ($selaimet muodossa $test_name => $browser) ( $ch = curl_init(); // määritä url curl_setopt($ch, CURLOPT_URL , $url); // määritä selaimen otsikot curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["kieli"] )" )); // emme tarvitse sivun sisältöä curl_setopt($ch, CURLOPT_NOBODY, 1); // meidän täytyy saada HTTP-otsikot curl_setopt($ch, CURLOPT_HEADER, 1); // palauttaa tulokset sen sijaan tulosteesta curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // oliko HTTP-uudelleenohjaus? if (preg_match("!Location: (.*)!", $output, $matches)) ( echo " $testin_nimi: uudelleenohjaukset kohteeseen $matches\n"; ) else ( echo "$test_name: ei uudelleenohjausta\n"; ) ) echo "\n\n"; )

Ensin määritämme luettelon tarkistettavien sivustojen URL-osoitteista. Tarkemmin sanottuna tarvitsemme näiden sivustojen osoitteet. Seuraavaksi meidän on määritettävä selaimen asetukset jokaisen URL-osoitteen testaamiseksi. Tämän jälkeen käytämme silmukkaa, jossa käymme läpi kaikki saadut tulokset.

Temppu, jota käytämme tässä esimerkissä cURL-asetusten määrittämiseen, antaa meille mahdollisuuden saada sivun sisällön sijaan vain HTTP-otsikot (tallennettuina $outputiin). Seuraavaksi yksinkertaisen säännöllisen lausekkeen avulla voimme määrittää, oliko merkkijono "Location:" vastaanotetuissa otsikoissa.

Kun juokset tämä koodi, sinun pitäisi saada jotain seuraavanlaisen tuloksen:

POST-pyynnön luominen tiettyyn URL-osoitteeseen

GET-pyyntöä muodostettaessa lähetetyt tiedot voidaan välittää URL-osoitteeseen "kyselymerkkijonon" kautta. Esimerkiksi kun teet haun Googlessa, hakutermit sijaitsevat kielellä osoitekenttä uusi URL-osoite:

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

Simuloidakseen tämä pyyntö, sinun ei tarvitse käyttää cURL-palveluita. Jos laiskuus voittaa sinut kokonaan, käytä "file_get_contents()"-funktiota saadaksesi tuloksen.

Mutta asia on, että jotkut HTML-lomakkeet lähettävät POST-pyyntö s. Näiden lomakkeiden tiedot kuljetetaan HTTP-pyynnön rungon kautta, ei kuten edellisessä tapauksessa. Jos esimerkiksi täytit lomakkeen foorumilla ja napsautit hakupainiketta, sinulle tehdään todennäköisesti POST-pyyntö:

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

Voimme kirjoittaa PHP-skriptin, joka voi simuloida tällaista URL-pyyntöä. Luodaan ensin yksinkertainen tiedosto POST-tietojen hyväksymiseksi ja näyttämiseksi. Kutsutaan sitä post_output.php:ksi:

Tulosta_r($_POST);

Sitten luomme PHP-skriptin cURL-pyynnön tekemiseksi:

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "Lähetä"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // osoittavat, että meillä on POST-pyyntö curl_setopt($ch, CURLOPT_POST, 1); // lisää muuttujat curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $tulostus = curl_exec($ch); curl_close($ch); echo $lähtö;

Kun suoritat tämän skriptin, sinun pitäisi saada tällainen tulos:

Siten POST-pyyntö lähetettiin post_output.php-skriptille, joka puolestaan ​​tulostaa superglobaalin $_POST-taulukon, jonka sisällön saimme käyttämällä cURL-osoitetta.

Tiedostoa ladataan

Luodaan ensin tiedosto sen luomiseksi ja lähettämiseksi upload_output.php-tiedostoon:

Tulosta_r($_FILES);

Ja tässä on komentosarjakoodi, joka suorittaa yllä mainitut toiminnot:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // ladattava tiedosto "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); $tulostus = curl_exec($ch); curl_close($ch); echo $lähtö;

Kun haluat ladata tiedoston, sinun tarvitsee vain välittää se tavallisena viestimuuttujana, jota edeltää @-symboli. Kun suoritat kirjoitetun skriptin, saat seuraavan tuloksen:

Useita cURL

Yksi kaikista vahvuuksia cURL on kyky luoda "useita" cURL-käsittelijöitä. Tämän avulla voit avata yhteyden useisiin URL-osoitteisiin samanaikaisesti ja asynkronisesti.

Klassisessa cURL-pyynnön versiossa komentosarjan suoritus keskeytetään ja odottaa pyynnön URL-toiminnon valmistumista, minkä jälkeen komentosarja voi jatkua. Jos aiot olla vuorovaikutuksessa kokonaisen joukon URL-osoitteita, tämä johtaa melko merkittävään aikainvestointiin, koska klassisessa versiossa voit työskennellä vain yhden URL-osoitteen kanssa kerrallaan. Voimme kuitenkin korjata tämän tilanteen käyttämällä erikoiskäsittelijöitä.

Katsotaanpa esimerkkikoodia, jonka otin php.net:stä:

// luoda useita cURL-resursseja $ch1 = curl_init(); $ch2 = curl_init(); // määritä URL-osoite ja muut parametrit 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); //luo usean cURL-käsittelijän $mh = curl_multi_init(); //lisää useita käsittelijöitä curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $aktiivinen = null; //suorita 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); ) ) //closing curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Ajatuksena on, että voit käyttää useita cURL-käsittelijöitä. Yksinkertaisen silmukan avulla voit seurata, mitä pyyntöjä ei ole vielä suoritettu.

Tässä esimerkissä on kaksi pääsilmukkaa. Ensimmäinen do-while -silmukka kutsuu curl_multi_exec()-funktiota. Tätä toimintoa ei voi estää. Se toimii niin nopeasti kuin mahdollista ja palauttaa pyynnön tilan. Niin kauan kuin palautettu arvo on vakio CURLM_CALL_MULTI_PERFORM, tämä tarkoittaa, että työ ei ole vielä valmis (esim. Tämä hetki lähetys on käynnissä http-otsikot URL-osoitteessa); Siksi tarkistamme tämän palautusarvon, kunnes saamme erilaisen tuloksen.

Seuraavassa silmukassa tarkistamme ehdon, kun muuttuja $active = "true". Se on curl_multi_exec()-funktion toinen parametri. Tämän muuttujan arvo on "true" niin kauan kuin jokin olemassa olevista muutoksista on aktiivinen. Seuraavaksi kutsumme curl_multi_select()-funktiota. Sen suoritus on "estetty", kun vähintään yksi aktiivinen yhteys on olemassa, kunnes vastaus saadaan. Kun näin tapahtuu, palaamme pääsilmukkaan jatkaaksemme kyselyjen suorittamista.

Sovelletaan nyt tätä tietoa esimerkkiin, joka on todella hyödyllinen suurelle joukolle ihmisiä.

Linkkien tarkistaminen WordPressissä

Kuvittele blogi, jossa on valtava määrä viestejä ja viestejä, joista jokainen sisältää linkkejä ulkoisiin Internet-resursseihin. Jotkut näistä linkeistä saattavat olla jo kuolleet eri syistä. Sivu on ehkä poistettu tai sivusto ei ehkä toimi ollenkaan.

Aiomme luoda skriptin, joka analysoi kaikki linkit ja löytää lataamattomat verkkosivustot ja 404-sivut, ja toimittaa sitten meille yksityiskohtaisen raportin.

Sanon heti, että tämä ei ole esimerkki WordPressin laajennuksen luomisesta. Tämä on ehdottoman hyvä testialusta testeillemme.

Aloitetaan vihdoin. Ensin meidän on noudettava kaikki linkit tietokannasta:

// määritys $db_host = "localhost"; $db_user = "juuri"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("paikallinen isäntä", "www.omaverkkotunnus.com"); $max_yhteydet = 10; // muuttujien alustus $url_list = array(); $työskentely_urls = array(); $dead_urls = array(); $not_found_urls = array(); $aktiivinen = null; // muodosta yhteys MySQL:ään if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("Ei voitu muodostaa yhteyttä: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Voisi not select db: " . mysql_error()); ) // valitse kaikki julkaistut viestit, joissa on linkkejä $q = "VALITSE post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post " "; $r = mysql_query($q) tai kuole(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // hae linkit käyttämällä säännöllisiä lausekkeita if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) ( foreach ($vastaa kuin $url) ( $tmp = parse_url($url) ; if (in_array($tmp["isäntä"], $suljetut_verkkotunnukset)) (jatka; ) $url_list = $url; ) ) ) // poista kaksoiskappaleet $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("Ei tarkistettavaa URL-osoitetta"); )

Ensin luomme konfigurointitiedot tietokannan kanssa vuorovaikutusta varten, sitten kirjoitamme luettelon verkkotunnuksista, jotka eivät osallistu tarkistukseen ($excluded_domains). Määritämme myös luvun, joka kuvaa skriptissämme käyttämiemme samanaikaisten yhteyksien enimmäismäärää ($max_connections). Liitymme sitten tietokantaan, valitsemme linkit sisältävät viestit ja keräämme ne taulukkoon ($url_list).

Seuraava koodi on hieman monimutkainen, joten käy se läpi alusta loppuun:

// 1. usean käsittelijän $mh = curl_multi_init(); // 2. lisää joukko URL-osoitteita kohteelle ($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; } }

Täällä yritän selittää kaiken yksityiskohtaisesti. Listan numerot vastaavat kommentissa olevia numeroita.

  1. 1. Luo useita käsittelijöitä;
  2. 2. Kirjoitamme add_url_to_multi_handle()-funktion hieman myöhemmin. Joka kerta kun sitä kutsutaan, uuden URL-osoitteen käsittely alkaa. Aluksi lisäämme 10 ($max_connections) URL-osoitetta;
  3. 3. Aloita suorittamalla curl_multi_exec()-funktio. Niin kauan kuin se palauttaa CURLM_CALL_MULTI_PERFORM, meillä on vielä tekemistä. Tarvitsemme tätä pääasiassa yhteyksien luomiseen;
  4. 4. Seuraavaksi tulee pääsilmukka, joka toimii niin kauan kuin meillä on vähintään yksi aktiivinen yhteys;
  5. 5. curl_multi_select() jumiutuu odottamaan URL-haun valmistumista;
  6. 6. Jälleen kerran meidän on saatava cURL tehdäksemme työtä, nimittäin noutaaksemme palautusvastaustiedot;
  7. 7. Tiedot tarkistetaan tästä. Pyynnön suorittamisen seurauksena taulukko palautetaan;
  8. 8. Palautettu taulukko sisältää cURL-käsittelijän. Käytämme sitä valitaksemme tiedot erillisestä cURL-pyynnöstä;
  9. 9. Jos linkki oli kuollut tai komentosarja aikakatkaistiin, meidän ei pitäisi etsiä http-koodia;
  10. 10. Jos linkki palautti meille 404-sivun, http-koodi sisältää arvon 404;
  11. 11. Muuten meillä on toimiva linkki edessämme. (Voit lisätä virhekoodin 500 tarkistuksia jne...);
  12. 12. Seuraavaksi poistamme cURL-käsittelijän, koska emme enää tarvitse sitä;
  13. 13. Nyt voimme lisätä toisen URL-osoitteen ja suorittaa kaiken, mistä puhuimme aiemmin;
  14. 14. Tässä vaiheessa skripti suorittaa työnsä. Voimme poistaa kaiken tarpeettoman ja luoda raportin;
  15. 15. Lopuksi kirjoitamme funktion, joka lisää url:n käsittelijään. Staattista muuttujaa $index kasvatetaan joka kerta tämä toiminto kutsutaan.

Käytin tätä kirjoitusta blogissani (joitakin rikkinäisiä linkkejä, jotka lisäsin tarkoituksella testatakseni sitä) ja sain seuraavan tuloksen:

Minun tapauksessani skriptillä kesti hieman alle 2 sekuntia indeksoida 40 URL-osoitetta. Tuottavuuden kasvu on merkittävää, kun työskentelee enemmän iso määrä URL-osoitteet. Jos avaat kymmenen yhteyttä samanaikaisesti, komentosarja voi suorittaa kymmenen kertaa nopeammin.

Muutama sana muista hyödyllisistä cURL-vaihtoehdoista

HTTP-todennus

Jos päällä URL-osoite Jos sinulla on HTTP-todennus, voit helposti käyttää seuraavaa komentosarjaa:

$url = "http://www.jokusivusto.fi/jäsenet/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // määritä käyttäjänimi ja salasana curl_setopt($ch, CURLOPT_USERPWD, "omakäyttäjänimi:omasalasana"); // jos uudelleenohjaus on sallittu curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // sitten tallenna tietomme hakemistoon cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $tulostus = curl_exec($ch); curl_close($ch);

FTP-lataus

PHP:llä on myös kirjasto FTP-työskentelyä varten, mutta mikään ei estä sinua käyttämästä cURL-työkaluja täällä:

// avaa tiedosto $tiedosto = fopen("/polku/tiedostoon", "r"); // URL-osoitteen tulee sisältää seuraava sisältö $url = "ftp://käyttäjänimi: [sähköposti suojattu]:21/polku/uuteen/tiedostoon"; $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, tiedostokoko("/polku/tiedostoon")); // määritä ASCII-modi curl_setopt($ch, CURLOPT_FTPASCII, 1); $lähtö = curl_exec ($ch); curl_close($ch);

Välityspalvelimen käyttäminen

Voit suorittaa URL-pyynnön välityspalvelimen kautta:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // määritä osoite curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // jos sinun on annettava käyttäjätunnus ja salasana curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $tulostus = curl_exec($ch); curl_close($ch);

Takaisinsoittotoiminnot

On myös mahdollista määrittää toiminto, joka käynnistyy ennen valmistumista cURL toimii pyyntö. Esimerkiksi vastauksen sisällön latautuessa voit aloittaa tietojen käytön odottamatta niiden latautumista kokonaan.

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

Tämänkaltaisen funktion TÄYTYY palauttaa merkkijonon pituus, mikä on vaatimus.

Johtopäätös

Tänään opimme, kuinka voit käyttää cURL-kirjastoa omiin itsekkäisiin tarkoituksiin. Toivottavasti pidit tästä artikkelista.

Kiitos! Hyvää päivänjatkoa!

Meillä on: php 5.2.3, Windows XP, Apache 1.3.33
Ongelma - cURL-moduulia ei havaita, jos PHP ajetaan Apachen alla
Kohdassa php.ini extension=php_curl.dll on kommentoimaton, extension_dir on asetettu oikein,
libeay32.dll ja ssleay32.dll kopioitiin kansioon c:\windows\system32.
Funktio phpinfo() ei kuitenkaan näytä cURL-moduulia asennettujen joukossa, ja kun Apache käynnistetään, lokiin kirjoitetaan seuraava:

PHP:n käynnistys: Dynaamista kirjastoa "c:/php/ext/php_curl.dll" ei voi ladata - Määritettyä moduulia ei löytynyt.

Jos suoritat php:n komentoriviltä, ​​cURL-komentoja sisältävät komentosarjat toimivat normaalisti, mutta jos suoritat sen Apachesta, ne tuottavat seuraavan:
Vakava virhe: Kutsu määrittelemättömään funktioon: curl_init() - riippumatta siitä, miten PHP on asennettu - CGI:nä tai moduulina.

Internetissä olen toistuvasti törmännyt tämän ongelman kuvaukseen - erityisesti cURL-moduulia varten, mutta siellä ehdotetut ratkaisut eivät auta. Lisäksi vaihdoin jo PHP 5.2:n versioon PHP 5.2.3 - se ei silti auttanut.

David Mzareulyan[asiakirja]
Minulla on yksi php.ini - tarkistin sen etsimällä levyltä. Sen, että käytetään samaa php.ini-ohjelmaa, vahvistaa helposti se, että siihen tehdyt muutokset vaikuttavat sekä komentosarjojen käynnistämiseen Apachesta että komentoriviltä.

Daniil Ivanov[asiakirja] Parempi tehdä tiedosto soittamalla

ja avaa se selaimella.
Ja suorita se sitten komentorivillä php linja-i | grep ini ja tarkista polut php.iniin sellaisena kuin php näkee ne, ei sen perusteella, onko tiedosto levyllä.

Daniil Ivanov[asiakirja] Mitä php -i tulostaa? Oletusbinaari saattaa etsiä konfiguraatiota eri paikasta käännösasetuksista riippuen. Tämä ei ole ensimmäinen kerta, kun olen törmännyt siihen, että mod_php.dll ja php.exe tarkastelevat eri ini-tiedostoja ja mikä toimii yhdessä, ei toimi toisessa.

Vasily Sviridov[asiakirja]
php -i tuottaa seuraavan:

Asetustiedosto (php.ini) Polku => C:\WINDOWS
Ladattu asetustiedosto => C:\PHP\php.ini

php.ini-tiedoston siirtäminen Windows-hakemistoon ei muuta tilannetta.

Daniil Ivanov[asiakirja]
Entä muut moduulit? Esimerkiksi php_mysql??? Yhdistää? Vai onko se vain cURL niin ilkeä?

Hmm, se ei myöskään lataudu minulle... Hyvin erilaisella kokoonpanolla (Apache 2.2 plus PHP 5.1.6 Zend Studiossa). Mutta siitä ei ole kysymys. Kokeilu Apachen käynnistämisellä komentoriviltä (tarkemmin FAR:sta) osoitti jotain mielenkiintoista. Yrittämättä yhdistää Curlia kaikki alkaa paketista. Kun yritän muodostaa yhteyden Kurliin, se antaa virheen tiedostossa... php5ts.dll.

Hei!
Minulla oli samanlainen ongelma, etsin ratkaisua pitkään, asensin lisää uusi versio RNR, löysin vihdoin tämän foorumin. Tässä ei ollut ratkaisua, joten yritin itse lisää.

Asensin Zend Studion, ja sitä ennen oli PHP:n aikaisempi versio. Ehkä jotkut heistä asensivat omat kirjastonsa, ja ne jäivät sinne - vanhentuneiksi.

Kiitos vinkeistä, erityisesti viimeisestä "Nehxbyn" vinkeistä. Menin hakemistoon C:\windows\system32 ja huomasin, että kirjastot libeay32.dll ja ssleay32.dll eivät ole samankokoisia kuin alkuperäiset. Asensin memcachedin, ehkä tämän jälkeen. Joten jos lisäsit jotain, mene system32:een :)

Minulla oli sama ongelma, käytin komentoa php -i | grep ini
osoitti, että kirjasto zlib1.dll puuttuu
se oli Apachen kansiossa, kirjoitin kopion kansioon PHP:llä
Toistin komennon, se osoitti, että zlib.dll-kirjasto puuttui, kirjoitin sen Apache-kansioon ja kaikki toimi.
ja kaikki kirjastot olivat myös php5ts.dll, joten ota huomioon kaikkien tarvittavien kirjastojen olemassaolo.

Päätin lisätä sen. Koska minäkin törmäsin tähän ongelmaan. Löysin tämän foorumin toisella sivustolla olevan linkin kautta. Yleensä kaikki ehdotetut vaihtoehdot eivät ole muuta kuin kainalosauvoja. ratkaisun ydin Windowsissa. sinun on asetettava PATH-muuttuja. osoittaa, missä PHP sijaitsee. ja hallelujah curl ei anna virheitä. kuten muutkin kirjastot...