La fonction Curl_Multi_ * fournit un bon support lors de l'utilisation d'extensions Curl pour les demandes HTTP simultanées dans PHP. En particulier, les deux fonctions Curl_Multi_Close et Curl_getInfo doivent souvent être utilisées ensemble pour gérer les réponses de plusieurs demandes. Cependant, dans le développement réel, les développeurs peuvent rencontrer certains pièges, en particulier lors de l'utilisation de Curl_getInfo pour obtenir les informations de réponse pour chaque demande. Si vous ne faites pas attention, cela peut entraîner des erreurs inattendues ou les informations correctes ne peuvent pas être obtenues.
CURL_MULTI_CLOSE est utilisé pour fermer plusieurs poignées de session Curl. Une fois la demande terminée, vous devez appeler cette fonction pour libérer toutes les ressources. Si vous utilisez Curl_getInfo pour obtenir les informations détaillées d'une demande avant de fermer la session, vous pouvez rencontrer un problème: après la fermeture de la session, les ressources associées à ces poignées de session sont détruites et vous ne pouvez pas obtenir les informations de réponse correctes en appelant Curl_getinfo .
// Exemple de code:Dans le mauvais sens
$mh = curl_multi_init();
$ch1 = curl_init("https://gitbox.net/api/v1/resource1");
$ch2 = curl_init("https://gitbox.net/api/v1/resource2");
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active);
// erreur:Appelé avant de fermer la poignée de session curl_getinfo
$info1 = curl_getinfo($ch1); // Une erreur se produira ici,Parce que la session a été fermée
$info2 = curl_getinfo($ch2);
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
Dans l'exemple ci-dessus, nous avons appelé Curl_getInfo avant Curl_Multi_Close , et les informations renvoyées ne sont plus disponibles et peuvent même entraîner des erreurs PHP.
Pour éviter les problèmes ci-dessus, vous devez utiliser Curl_getInfo pour obtenir les informations de réponse pour chaque demande avant d'appeler CURL_MULTI_CLOSE . Voici une bonne démonstration après la modification:
// La bonne façon de le faire
$mh = curl_multi_init();
$ch1 = curl_init("https://gitbox.net/api/v1/resource1");
$ch2 = curl_init("https://gitbox.net/api/v1/resource2");
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active);
// correct:Obtenez des informations de réponse avant de fermer la session
$info1 = curl_getinfo($ch1);
$info2 = curl_getinfo($ch2);
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
// Maintenant, vous pouvez l'utiliser en toute sécurité $info1 et $info2 C'est
Dans cette version modifiée, nous nous assurons qu'avant la fermeture de toutes les poignées de session, nous obtenons les informations de réponse pour chaque demande via Curl_getInfo . Cela évite d'essayer d'accéder à la ressource déjà publiée après la fermeture de la poignée de session, provoquant une erreur.
Si vous envoyez plusieurs demandes en même temps et que vous souhaitez obtenir des informations de réponse pour chaque demande, vous utiliserez généralement une boucle. Pour le moment, vous devez vous assurer que chaque curl_getinfo demandé est obtenue avant Curl_Multi_Close , sinon une perte de ressources se produira.
// correct的做法:Utilisez une boucle pour obtenir des informations pour chaque demande une par une
$mh = curl_multi_init();
$channels = [];
$urls = [
"https://gitbox.net/api/v1/resource1",
"https://gitbox.net/api/v1/resource2"
];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_multi_add_handle($mh, $ch);
$channels[] = $ch;
}
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active);
foreach ($channels as $ch) {
$info = curl_getinfo($ch); // Obtenez des informations un par un ici
// traiter avec $info
}
foreach ($channels as $ch) {
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
Dans cet exemple, nous utilisons un tableau pour stocker chaque poignée de session Curl et obtenir les informations de réponse pour chaque demande une par une avant Curl_Multi_Close . Cette approche évite les problèmes mentionnés précédemment.
Parfois, toutes les demandes ne seront pas remplies en même temps. Pour éviter d'appeler Curl_getInfo sur des demandes inachevées, vous pouvez utiliser la fonction Curl_Multi_Select pour détecter les demandes qui ont été remplies, en vous assurant que vous n'appelez que Curl_getinfo sur les demandes terminées.
// Situations plus complexes:utiliser curl_multi_select traiter avec完成的请求
$mh = curl_multi_init();
$channels = [];
$urls = [
"https://gitbox.net/api/v1/resource1",
"https://gitbox.net/api/v1/resource2"
];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_multi_add_handle($mh, $ch);
$channels[] = $ch;
}
do {
$mrc = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh); // Attendez une demande pour terminer
}
} while ($active);
foreach ($channels as $ch) {
$info = curl_getinfo($ch); // Obtenez les informations de demande terminées ici
// traiter avec $info
}
foreach ($channels as $ch) {
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
L'utilisation de curl_multi_select garantit que les informations sont obtenues à temps lorsque la demande est terminée, évitant ainsi la perte de données en raison de problèmes d'attente ou de délai d'attente.
Lorsque vous utilisez la fonction Curl_Multi_ * dans PHP, Curl_getInfo et Curl_Multi_Close sont des outils couramment utilisés. La clé pour éviter les pièges courants est de s'assurer que les informations de réponse pour chaque session ont été obtenues via Curl_getInfo avant de fermer plusieurs sessions. Avec la bonne structure de code et la gestion des demandes, vous pouvez assurer la stabilité et l'exactitude de votre programme.