J'ai un bot DiscordPHP et j'essaie de télécharger des pages Web qui nécessitent des cookies. Il semble que je doive utiliser le gestionnaire curl avec Guzzle car le navigateur http ReactPHP ne prend pas en charge les cookies.
J'ai créé ce script minimal :
use GuzzleHttp\Client; use GuzzleHttp\Handler\CurlMultiHandler; use GuzzleHttp\HandlerStack; use Psr\Http\Message\ResponseInterface; include 'vendor/autoload.php'; $loop = \React\EventLoop\Loop::get(); $curl = new CurlMultiHandler; $handler = HandlerStack::create($curl); $client = new Client( [ /* 'cookies' => $cookieJar, */ 'handler' => $handler ] ); $promise = $client->getAsync('https://httpstat.us/200') ->then( function (ResponseInterface $res) { echo 'response: ' . $res->getStatusCode() . PHP_EOL; }, function (\Exception $e) { echo $e->getMessage() . PHP_EOL; } ); $timer = $loop->addPeriodicTimer(0.5, function () use ($curl, $promise) { if ($promise->getState() === 'pending') { echo 'Tick '; $curl->tick(); } echo 'Beat '; }); $loop->run();
Cela se terminera immédiatement sans ajouter le code addPeriodicTimer
来检查挂起并手动调用 tick()
:
$ time php minimal.php 0.022u 0.010s 0:00.03 100.0% 0+0k 0+0io 67pf+0w
En utilisant la minuterie, cela fonctionne comme prévu :
Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick Beat Tick response: 200 Beat Beat Beat ...
L'idée d'utiliser tick()
est venue de ce fil de discussion fermé de 73 commentaires sur github.com.
Il existe quelques questions similaires, mais aucune ne semble résoudre ce problème :
wait()
Il s’agit d’un appel bloquant. sleep()
调用,ReactPHP 真的是异步的吗?执行一个长 for
. Les deux bloquent la boucle. Comment utiliser Cookie Jar pour lancer HTTP GET
et obtenir une réponse dans la boucle d'événements ReactPHP sans utiliser d'appels bloquants (tels que ->wait()
ou manuel GET
并在 ReactPHP 事件循环中获取响应,而不使用阻塞调用(例如 ->wait()
或手动 tick()
ing curl 强>
Eh bien, ReactPHP ne définit pas les cookies automatiquement, il existe déjà un ticket traitant de ce sujet : https://github.com/reactphp/http/issues/445, mais vous pouvez toujours définir l'en-tête du cookie HTTP manuellement.
Il convient également de mentionner que l'utilisation de ReactPHP avec Guzzle ne fonctionnera pas car Guzzle bloque la boucle d'événements de ReactPHP. Cela signifie que vous pouvez envoyer plusieurs requêtes, mais que vous ne pouvez rien faire d'autre de manière asynchrone.