php ile istekleri olmayan engelleme ve uyku ile çalışmıyor kıvırmak

2 Cevap php

Ben asenkron engellenmeyen isteklerini sağlamak için curl_multi_ * kod bilinen cURL özelliğini kullanmak için küçük bir script kurdunuz, bu kodun bir kaba versiyonu:

$mch = curl_multi_init();
$ch = curl_init();

url_setopt($ch, CURLOPT_URL,         $url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);          

curl_multi_add_handle($mch ,$ch);
$running = null;
do {
    curl_multi_exec($mch ,$running);
} while($running > 0);

curl_multi_remove_handle($mch,$ch);
curl_close($ch);

temelde bu başka bir komut dosyası cURL aracılığıyla denir iken çalışmasını sağlamak için kod izin paralel bir istek gibi bir isteği göndermek için kullanılır, ben bu yüzden ben sadece diğer komut olmak istiyorum bunu işlemek için hiçbir kod kullanılan sonuç için umurumda değil kıvırmak çağrısından sonra kod çalışmaya devam ederken çağırdı.

neden tek bir isteği iş için bir kez multi_exec çağrısında olmaz, while döngüsü gerekiyor her şeyden önce ben anlamıyorum? döngüsünü kullanmadan beri (son kontrol) $ url üzerinde komut çalışmaz.

ikincisi ve benim en büyük sorun, bu uyumsuz olmalı, ben diğer senaryo üzerinde uyku (10) koyarak denedim ve çağıran komut devam etmeden önce 10 saniye bekler, ben bu engellenmeyen olmalı dont almak ve çalışmaya devam etmelidir.

Ben yanlış ne yapıyorum?

2 Cevap

Sondan başlayalım.

PHP sizin komut çalışması tamamlandığında, bu bir temizlik yapar ve tüm hala çalışıyor kıvırmak kolları kapalı öldürür. O hatırlamak önemlidir.

Şimdi, her kıvırmak isteği, bağlantı başlatılırken bağlantı, veri yazma, veri okuma, bağlantıyı kapatmadan gibi, birden fazla aşamada ayrılır. Orta adımlar tekrar edilebilir. Ve ben aslında perde arkasında neler daha karmaşık şeyler vardır, ama genel olarak bu açıklama doğru olmalı emin değilim.

curl_multi_exec çoklu kolu kolları her denetimi verir ve o ne olursa olsun, bir sonraki adımı, gerçekleştirmek için izin verir. Ve sonra işlevini verir.

Eğer döngü olmadan isteği görmüyorsanız açıklıyor. Sapınızın henüz fiili bağlantıyı gerçekleştirmek mümkün adımı ulaşmış değil çünkü o olur. Sizin PHP komut dosyası, çalışmasını bitirdiğinde hiç bir şey yapmak için hiçbir şansı var sırayla kolu öldürür temizleme, gerçekleştirir.

Yani, artık bir şeyler yapmak için kolu şans vermek gerekiyor net olduğunu. Tekrar tekrar curl_multi_exec Koşu bunu başarmak için tek yoldur.

Eğer beklemek yaşandığı açıklıyor, bu çok kolları onlar gibi onlar sadece bakmak, gerçekten uyumsuz değildir. Sizin döngüsü çalıştırmak ve istek (sizin örnekte 10 saniye sürer) bitinceye kadar döngü çalışmaya devam edecektir kolu şans verir.

Kısa özeti: (curl yürütülürken, başka kod çalıştırma tutmak için) senin sorunun başka bir çözüm bulmak gerekir :)

Bu benim için iyi çalışır:

function get_web_page( $url )
{
$options = array(
    CURLOPT_RETURNTRANSFER => true,     // return web page
    CURLOPT_HEADER         => false,    // don't return headers
    CURLOPT_FOLLOWLOCATION => true,     // follow redirects
    CURLOPT_ENCODING       => "",       // handle all encodings
    CURLOPT_USERAGENT      => "spider", // who am i
    CURLOPT_AUTOREFERER    => true,     // set referer on redirect
    CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
    CURLOPT_TIMEOUT        => 120,      // timeout on response
    CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
);

$ch      = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err     = curl_errno( $ch );
$errmsg  = curl_error( $ch );
$header  = curl_getinfo( $ch );
curl_close( $ch );

$header['errno']   = $err;
$header['errmsg']  = $errmsg;
$header['content'] = $content;
return $header;
}

Bir fonksiyonu olarak ve üzerinde arayabilirsiniz. (Asenkron parçacıkları gibi) Yani gerçekten yapmanız gerekir tüm bu script kod sorunu sonunda durdurmak kaçınarak, bitirebiliriz yapılır kez .. tüm alınan bukleler alma ve işleme işlemek için bir süre döngü yazmak değildir.

Başka bir nokta .. Eğer süre böyle döngüler biçimlendirmek için ihtiyacım yok ..

do { ... } while (conditional)

Sadece kullanabilirsiniz:

while (conditional) { ... }