Asynchronní dotazy v CURL
Školení, která pořádám
Extenze CURL nabízí podporu asynchronních požadavků. A podobně jako MySQLi neposkytuje zrovna přívětivé API. Vytvořil jsem proto knihovnu, která pokládání vícenásobných požadavků usnadní:
<?php
$http = new CurlAsync;
// položení požadavků
$http->test1("http://www.example.com/");
$http->test2("http://www.example.org/");
// získání odpovědí
print_r($http->test1());
print_r($http->test2());
?>
Knihovna je k dispozici na GitHubu.
Motivace pro asynchronní získávání dat je stejná jako u databáze: výkonnost. Stažení externích URL je obvykle časově náročné, takže hlavně když jich potřebujeme získat víc, vyplatí se to dělat na pozadí. Pokud očekáváme odpověď rychle, lze nastavit $http->timeout = .1
.
Diskuse
Pardon, ale koukal jsem na to asi tak minutu, i na to předchozí, možná jsem něco přehlédl, ale tohle mi přijde jako fakt hnus, jquery určitě znáš když ho školíš, tak proč ne stejně jednoduše, např.
<?php
$async = new CurlAsync;
$async->get("http://www.example.com/", function(){});
?>
místo té lambdy může být i 5.2 callback. Takhle to dělá jquery, node.js ... ta lambda z toho udělá teprve to pravé async. Odpadne také brzdící velehnus __call().
Současné API byl jen takový pokus. Mám v plánu ho předělat, aby šel přidat interface. Ale callback předávat nebudu, způsob použití tomu neodpovídá. Na vrácená data potřebuješ počkat třeba v šabloně a použít je v určitém kontextu.
No a brát si jako protipříklad zrovna jQuery není úplně nejšťastnější vzhledem k existenci metod jako click(callback), které naváže událost, VS click(), které ji spustí. To je přesně stejná myšlenka.
alternate:
Pardon, ale celé PHP s javascriptem je pomalej velehnus:), doufám že se tento trend brzo změní, nerad bych se dožil doby, kde se video v prohlížeči bude renderovat sw javascriptovým kodekem:)
V pohodě, s php souhlas, s javascriptem ale ne, js vm udělaly za posledních pár let v optimalizaci proti PHP veleskok (abych zůstal u toho velesloví). Dokonce JITují už skoro všechny. Když se nepoužívá eval a ostatní brzdy, javascript bych řekl už na tom bude co se týče optimalizace mnohem lépe než php. A mě představa, že za pár let se bude psát většina aplikací v JS jak na serveru, tak na klientu vůbec nevadí.
optik:
Ne, to není skok dopředu, ale stranou a to je pro majoritu uživatelů php k ničemu u JS engines je situace naprosto odlišná, tam ty vylepšení zasahují v postatě všechny.
optik:
Jojo, škoda že Http PECL extenze u dávno není v core, myslím, že by mohla ušetřit spoustě frameworkům práci.
starenka:
Jen tak zběžně jsem to prolít' na telefonu, kdyžtak mě po(p)opravte. Chapu to správně, že nejde přidávat vlastní "setopts"?
Jakub Vrána :
Přesně tak, chtěl jsem co nejjednodušší API. Alternativou by bylo předávat výsledek curl_init($url).
Martin:
Z nějakého důvodu mi nic z výše uvedeného nefungovalo (IIS 7 ?). Nakonec se mi ale podařilo najít funkci, která to zvládá bez problémů. Zavolá stránku a nečeká na výsledek. Pokud na začátek volané stránky dáte ignore_user_abort(true);, tak se vykoná.
<?php
// open a page and don't wait for the result
function curlPostAsync($url, $post_string = "")
{
$parts = parse_url($url);
$fp = fsockopen($parts['host'],
isset($parts['port']) ? $parts['port'] : 80,
$errno, $errstr, 30);
$out = "POST ".$parts['path']." HTTP/1.1\r\n";
$out.= "Host: ".$parts['host']."\r\n";
$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
$out.= "Content-Length: ".strlen($post_string)."\r\n";
$out.= "Connection: Close\r\n\r\n";
if ( isset($post_string))
$out .= $post_string;
fwrite($fp, $out);
fclose($fp);
}
?>
Diskuse je zrušena z důvodu spamu.