Les fonctions Curl_Multi_ * Series sont des outils très importants lors de l'utilisation de l'extension Curl de PHP pour les demandes simultanées. CURL_MULTI_CLOSE est responsable de la fermeture d'une manche multi-multiples , mais si elle est mal utilisée, cela peut facilement conduire à un statut de connexion anormal, tel que: certaines demandes ne sont pas remplies, les ressources ne sont pas correctement publiées et des délais d'attente inexplicables se produisent. Alors, comment pouvons-nous éviter ces exceptions gracieusement et correctement? Cet article expliquera en détail.
Lorsque de nombreux développeurs traitent les demandes simultanées, le code peut ressembler à ceci:
<?php
$mh = curl_multi_init();
$ch1 = curl_init('https://gitbox.net/api/endpoint1');
$ch2 = curl_init('https://gitbox.net/api/endpoint2');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Démarrer et exécuter
do {
$status = curl_multi_exec($mh, $active);
curl_multi_select($mh);
} while ($active && $status == CURLM_OK);
// Fermer directement
curl_multi_close($mh);
Le problème avec cette méthode d'écriture est que même si la demande n'a pas été entièrement traitée (en particulier lorsque les conditions du réseau sont médiocres), Curl_Multi_Close est appelée directement, ce qui entraînera une résiliation de certaines connexions à peu près et, par conséquent, une anomalie d'état se produira naturellement.
Avant d'appeler CURL_MULTI_CLOSE , vous devez vous assurer que toutes les poignées ( poignée Curl ) ont été traitées et elles sont supprimées! Le processus correct doit être:
CURL_MULTI_EXEC est appelé à plusieurs reprises jusqu'à ce que toutes les demandes soient remplies.
Supprime chaque poignée de boucle individuelle ( curl_multi_remove_handle ).
Fermez séparément une seule poignée Curl ( curl_close ).
Enfin, fermez plusieurs manches ( curl_multi_close ).
L'exemple de code modifié est le suivant:
<?php
$mh = curl_multi_init();
$ch1 = curl_init('https://gitbox.net/api/endpoint1');
$ch2 = curl_init('https://gitbox.net/api/endpoint2');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Démarrer et exécuter
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
// Retirer et fermer un seul handle
curl_multi_remove_handle($mh, $ch1);
curl_close($ch1);
curl_multi_remove_handle($mh, $ch2);
curl_close($ch2);
// Dernière clôture multi handle
curl_multi_close($mh);
curl_multi_remove_handle doit être fait avant Curl_Multi_Close .
Même si la connexion n'a pas demandé, elle doit être nettoyée correctement via Remove_Handle + Close .
L'utilisation de curl_multi_select dans une boucle peut réduire l'utilisation du processeur et éviter d'attendre d'attente.
Essayez d'attraper des erreurs (telles que Curl_errno et Curl_error ) et ne faites pas aveuglément confiance à la demande de réussite.
Dans les scénarios de concurrence élevés, les détails déterminent le succès ou l'échec. L'essence de curl_multi_close est juste de détruire la poignée multiple, ce qui ne garantit pas et ne peut pas garantir la fermeture sécurisée de toutes les connexions uniques. Par conséquent, avant de fermer la manche multiple, assurez-vous de retirer et de fermer manuellement chaque poignée individuelle , qui est la clé pour éviter les exceptions d'état de connexion.
Suivre le processus de traitement correct peut permettre à vos demandes simultanées d'exécuter de manière stable et efficace, loin de ces bogues cachés sujets aux céphalées.