Dans PHP, Curl est une bibliothèque puissante pour l'échange de données avec d'autres serveurs. Il permet aux développeurs d'envoyer et de recevoir des données via des demandes HTTP. Après avoir terminé une demande Curl, nous utilisons généralement la fonction Curl_close pour fermer la session Curl et libérer les ressources.
$ch = curl_init("https://gitbox.net/some-api-endpoint");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
Dans cet exemple, après que Curl_close ($ ch) est appelé, nous nous attendons à ce que les ressources occupées par la variable $ ch soient publiées.
Si la mémoire est toujours occupée après avoir utilisé Curl_close , il peut y avoir plusieurs aspects de la raison. Voici quelques raisons courantes:
Mécanisme de gestion de la mémoire PHP
PHP utilise un mécanisme qui retarde la collecte des ordures. Même si Curl_close est appelé, la libération de la mémoire peut ne pas se produire immédiatement. PHP peut attendre que l'exécution du script soit terminée avant de recycler ces ressources.
Curl_init et curl_close plusieurs fois
Si vous initialisez et fermez les ressources en boucle plusieurs fois dans le même script, PHP peut ne pas publier les ressources précédentes immédiatement, surtout lorsqu'il y a un grand nombre de demandes. Chaque fois qu'une nouvelle session Curl est créée, il prend une certaine quantité de mémoire et ne sera pas complètement nettoyé avant la fin de l'exécution du script.
La ressource en boucle n'est pas complètement fermée <br> Si une erreur se produit avant d'appeler CURL_CLOSE , ou si vous ne vous assurez pas que la session Curl a été exécutée correctement, la ressource peut ne pas être entièrement publiée. Par exemple, Curl_exec renvoie false sans obtenir le message d'erreur via curl_error .
Bien que Curl_close soit utilisé pour libérer des ressources, il ne suffit parfois pas d'assurer la libération complète de la mémoire. Voici quelques façons d'essayer:
L'utilisation d'un unset peut aider à effacer les variables PHP, ce qui aide à libérer la mémoire plus rapidement. Même si Curl_close a été exécuté, unset garantit que la variable ne fait plus référence à la ressource.
curl_close($ch);
unset($ch);
En PHP, la collection de déchets est automatiquement effectuée, mais elle peut être obligée d'effectuer une collection de déchets en appelant manuellement GC_COLLECT_CYCLES pour s'assurer que les ressources sont recyclées dans le temps.
curl_close($ch);
unset($ch);
gc_collect_cycles();
Si vous constatez que l'utilisation de la mémoire est encore trop élevée, vous pouvez utiliser Memory_get_usage et Memory_get_peak_usage pour analyser l'utilisation de la mémoire. Cela vous aidera à comprendre plus clairement si la mémoire est réellement libérée.
echo "Utilisation actuelle de la mémoire: " . memory_get_usage() . " bytes";
echo "Utilisation maximale de la mémoire: " . memory_get_peak_usage() . " bytes";
Si vous exécutez un grand nombre de demandes Curl, envisagez de traiter les demandes par lots au lieu d'exécuter toutes les demandes à la fois. Cela aide non seulement la gestion de la mémoire, mais réduit également la charge du serveur.
// Traiter plusieurs demandes de lots
$urls = [
"https://gitbox.net/api1",
"https://gitbox.net/api2",
"https://gitbox.net/api3",
];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
unset($ch);
}
Pour les situations où plusieurs demandes doivent être exécutées, l'utilisation des fonctions multithreades de Curl (telles que les fonctions Curl_Multi_ * ) peut réduire efficacement l'utilisation de la mémoire et accélérer les demandes. Multithreading peut exécuter plusieurs demandes simultanément, réduisant l'utilisation de la mémoire d'une seule demande.
$multiHandle = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$handles[] = $ch;
}
do {
curl_multi_exec($multiHandle, $running);
} while ($running > 0);
foreach ($handles as $ch) {
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);