Existe-t-il un moyen en PHP de faire des appels HTTP asynchrones? Je ne me soucie pas de la réponse, je veux juste faire quelque chose comme file_get_contents()
, mais pas attendre la fin de la demande avant d'exécuter le reste de mon code. Ce serait super utile pour déclencher des "événements" d'une sorte dans mon application, ou déclencher de longs processus.
Des idées?
php
http
asynchronous
Brent
la source
la source
Réponses:
La réponse que j'avais précédemment acceptée ne fonctionnait pas. Il attendait toujours les réponses. Cela fonctionne cependant, tiré de Comment puis-je faire une demande GET asynchrone en PHP?
la source
curl_post_async
et obtenir même des votes positifs ...Si vous contrôlez la cible que vous souhaitez appeler de manière asynchrone (par exemple, votre propre "longtask.php"), vous pouvez fermer la connexion à cette fin et les deux scripts s'exécuteront en parallèle. Cela fonctionne comme ceci:
J'ai essayé cela, et cela fonctionne très bien. Mais quick.php ne saura rien sur la durée de longtask.php, sauf si vous créez des moyens de communication entre les processus.
Essayez ce code dans longtask.php, avant de faire quoi que ce soit d'autre. Il fermera la connexion, mais continuera à fonctionner (et supprimera toute sortie):
Le code est copié à partir des notes fournies par l'utilisateur du manuel PHP et quelque peu amélioré.
la source
while(true);
après votre code. La page va se bloquer, cela signifie qu'elle est toujours en cours d'exécution au premier plan.Vous pouvez faire de la ruse en utilisant exec () pour appeler quelque chose qui peut faire des requêtes HTTP, comme
wget
, mais vous devez diriger toutes les sorties du programme vers quelque part, comme un fichier ou / dev / null, sinon le processus PHP attendra cette sortie .Si vous voulez séparer complètement le processus du thread apache, essayez quelque chose comme (je ne suis pas sûr de cela, mais j'espère que vous avez l'idée):
Ce n'est pas une bonne affaire, et vous voudrez probablement quelque chose comme un travail cron invoquant un script de pulsation qui interroge une file d'attente d'événements de base de données réelle pour faire de vrais événements asynchrones.
la source
exec("curl $url > /dev/null 2>&1 &");
est l'une des solutions les plus rapides ici. C'est immensément plus rapide (1,9 s pour 100 itérations) que lapost_without_wait()
fonction (14,8 s) dans la réponse «acceptée» ci-dessus. ET c'est unDepuis 2018, Guzzle est devenu la bibliothèque standard de facto pour les requêtes HTTP, utilisée dans plusieurs frameworks modernes. Il est écrit en PHP pur et ne nécessite aucune installation d'extensions personnalisées.
Il peut très bien faire des appels HTTP asynchrones et même les regrouper, par exemple lorsque vous devez effectuer 100 appels HTTP, mais que vous ne souhaitez pas exécuter plus de 5 appels à la fois.
Exemple de demande simultanée
Voir http://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests
la source
la source
&
à la fin?Vous pouvez utiliser cette bibliothèque: https://github.com/stil/curl-easy
C'est assez simple alors:
Ci-dessous, vous pouvez voir la sortie de la console de l'exemple ci-dessus. Il affichera une horloge en direct simple indiquant combien de temps la demande est en cours d'exécution:
la source
Faux une demande d'avortement en utilisant
CURL
un réglage basCURLOPT_TIMEOUT_MS
configuré
ignore_user_abort(true)
pour continuer le traitement après la fermeture de la connexion.Avec cette méthode, pas besoin d'implémenter la gestion des connexions via des en-têtes et un tampon trop dépendants de la version OS, Browser et PHP
Processus maître
Processus d'arrière-plan
NB
Ressources
le délai de bouclage inférieur à 1000 ms échoue toujours?
http://www.php.net/manual/en/function.curl-setopt.php#104597
http://php.net/manual/en/features.connection-handling.php
la source
permettez-moi de vous montrer mon chemin :)
nécessite nodejs installé sur le serveur
(mon serveur envoie 1000 https pour obtenir une requête en 2 secondes seulement)
url.php:
urlscript.js>
la source
L'extension Swoole. https://github.com/matyhtf/swoole Framework de réseau asynchrone et simultané pour PHP.
la source
Vous pouvez utiliser des sockets non bloquants et l'une des extensions pecl pour PHP:
Vous pouvez utiliser une bibliothèque qui vous donne une couche d'abstraction entre votre code et une extension pecl: https://github.com/reactphp/event-loop
Vous pouvez également utiliser le client http asynchrone, basé sur la bibliothèque précédente: https://github.com/reactphp/http-client
Voir d'autres bibliothèques de ReactPHP: http://reactphp.org
Soyez prudent avec un modèle asynchrone. Je recommande de voir cette vidéo sur youtube: http://www.youtube.com/watch?v=MWNcItWuKpI
la source
la source
Extension d'événement
L' extension d' événement est très appropriée. Il s'agit d'un port de la bibliothèque Libevent conçu pour les E / S événementielles, principalement pour la mise en réseau.
J'ai écrit un exemple de client HTTP qui permet de planifier un certain nombre de requêtes HTTP et de les exécuter de manière asynchrone.
Il s'agit d'un exemple de classe client HTTP basée sur l' extension d' événement .
La classe permet de planifier un certain nombre de requêtes HTTP, puis de les exécuter de manière asynchrone.
http-client.php
test.php
Il s'agit d'un exemple de script côté serveur.
Usage
Exemple de sortie
(Découpé.)
Remarque, le code est conçu pour un traitement à long terme dans l' interface CLI SAPI .
Pour les protocoles personnalisés, envisagez d'utiliser une API de bas niveau, c'est-à-dire des événements de tampon , des tampons . Pour les communications SSL / TLS, je recommanderais l'API de bas niveau en conjonction avec le contexte SSL de l'événement . Exemples:
Bien que l'API HTTP de Libevent soit simple, elle n'est pas aussi flexible que les événements de tampon. Par exemple, l'API HTTP ne prend actuellement pas en charge les méthodes HTTP personnalisées. Mais il est possible d'implémenter pratiquement n'importe quel protocole à l'aide de l'API de bas niveau.
Extension Ev
J'ai également écrit un échantillon d'un autre client HTTP utilisant l' extension Ev avec des sockets en mode non bloquant . Le code est légèrement plus détaillé que l'exemple basé sur Event, car Ev est une boucle d'événement à usage général. Il ne fournit pas de fonctions spécifiques au réseau, mais son
EvIo
observateur est capable d'écouter un descripteur de fichier encapsulé dans la ressource socket, en particulier.Il s'agit d'un exemple de client HTTP basé sur l' extension Ev .
L'extension Ev implémente une boucle d'événements à usage général simple mais puissante. Il ne fournit pas d'observateurs spécifiques au réseau, mais son observateur d'E / S peut être utilisé pour le traitement asynchrone des sockets .
Le code suivant montre comment les requêtes HTTP peuvent être planifiées pour un traitement parallèle.
http-client.php
Essai
Supposons que le
http://my-host.local/test.php
script imprime le vidage de$_GET
:La sortie de la
php http-client.php
commande sera alors similaire à la suivante:(coupé)
Remarque, en PHP 5 , la prises extension peut connecter des avertissements pour
EINPROGRESS
,EAGAIN
et lesEWOULDBLOCK
errno
valeurs. Il est possible de désactiver les journaux avecConcernant "le reste" du code
Le code qui est censé s'exécuter en parallèle avec les requêtes réseau peut être exécuté dans le rappel d'un temporisateur d'événement , ou l' observateur inactif d'Ev , par exemple. Vous pouvez facilement le découvrir en regardant les échantillons mentionnés ci-dessus. Sinon, je vais ajouter un autre exemple :)
la source
Voici un exemple de travail, lancez-le et ouvrez ensuite storage.txt, pour vérifier le résultat magique
la source
Voici ma propre fonction PHP lorsque je fais du POST vers une URL spécifique de n'importe quelle page .... Exemple: *** utilisation de ma fonction ...
la source
ReactPHP async http client
https://github.com/shuchkin/react-http-client
Installer via Composer
Async HTTP GET
Exécutez php en mode CLI
la source
Je trouve ce package assez utile et très simple: https://github.com/amphp/parallel-functions
Il chargera les 3 URL en parallèle. Vous pouvez également utiliser des méthodes d'instance de classe dans la fermeture.
Par exemple, j'utilise l'extension Laravel basée sur ce package https://github.com/spatie/laravel-collection-macros#parallelmap
Voici mon code:
Il charge toutes les données nécessaires dans 10 threads parallèles et au lieu de 50 secondes sans asynchronisation, il s'est terminé en seulement 8 secondes.
la source
Symfony HttpClient est asynchrone https://symfony.com/doc/current/components/http_client.html .
Par exemple, vous pouvez
la source
Eh bien, le délai peut être défini en millisecondes, voir "CURLOPT_CONNECTTIMEOUT_MS" dans http://www.php.net/manual/en/function.curl-setopt
la source