Lorsque PHP utilise Curl pour effectuer plusieurs demandes HTTP, nous voulons parfois partager certaines données entre plusieurs demandes, telles que les cookies, les caches DNS ou les séances SSL. À l'heure actuelle, vous pouvez utiliser Curl_share_Init () et les fonctions connexes pour réaliser le partage. Cependant, de nombreux développeurs rencontrent un problème commun lorsque vous essayez d'utiliser la fonctionnalité: cet article analysera en détail les causes et les solutions de ce problème.
Tout d'abord, passons rapidement en revue comment utiliser curl_share_init pour partager des cookies:
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
$ch1 = curl_init('https://m66.net/login');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_COOKIEFILE, '');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
// Supposons que cette demande sera définie Cookie
$response1 = curl_exec($ch1);
$ch2 = curl_init('https://m66.net/profile');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_COOKIEFILE, '');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
// J'espère que cela enverra les derniers paramètres demandés ici Cookie
$response2 = curl_exec($ch2);
curl_close($ch1);
curl_close($ch2);
curl_share_close($sh);
D'après la logique du code, nous nous attendons à réaliser le partage des cookies via Curl_lock_data_cookie de curl_share_setopt () . Mais de nombreux développeurs ont rapporté que la deuxième demande n'est pas livrée avec le cookie renvoyé par la première demande .
Bien que nous définissions des cookies partagés, libcurl n'enregistrera pas ou n'écrira pas automatiquement des cookies par défaut, sauf si c'est défini:
Curlopt_cookiefile : lire les fichiers de cookies existants
Curlopt_cookiejar : écrivez un fichier de cookie après la demande
Défini sur '' (String vide) peut activer le traitement des cookies en mémoire, mais cette méthode peut être instable lorsqu'elle est combinée avec Curl_share_ * .
L'extension Curl de PHP utilise la bibliothèque Libcurl . Sur certaines plateformes ou versions, le comportement de Curl_share_ * peut différer légèrement de la description officielle de la documentation, en particulier les parties impliquant des cookies. CURL_LOCK_DATA_COOKIE est plus conçu pour être utilisé par Libcurl de bas niveau, tandis que la méthode d'appel après PHP est encapsulée de manière incohérente.
Les cookies ont des restrictions de chemin (chemin) et de domaine (domaine). Si le nom de domaine URL demandé est différent (même si le nom de sous-domaine est différent), le cookie ne sera pas envoyé. De même, si le cookie défini par le serveur n'est valable que pour un chemin spécifique et que le chemin demandé suivant n'est pas inclus, le cookie ne sera pas automatiquement attaché.
L'utilisation de fichiers de cookies temporaires pour la gestion explicite est le moyen le plus simple et le plus fiable.
$tmpCookieFile = tempnam(sys_get_temp_dir(), 'cookie');
$ch1 = curl_init('https://m66.net/login');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_COOKIEJAR, $tmpCookieFile);
curl_setopt($ch1, CURLOPT_COOKIEFILE, $tmpCookieFile);
$response1 = curl_exec($ch1);
$ch2 = curl_init('https://m66.net/profile');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_COOKIEJAR, $tmpCookieFile);
curl_setopt($ch2, CURLOPT_COOKIEFILE, $tmpCookieFile);
$response2 = curl_exec($ch2);
Cette méthode ne s'appuie pas sur curl_share_ * et garantit que les cookies peuvent être stockés et rechargés, et convient à la plupart des projets PHP.
Si vous devez contrôler les cookies plus attentivement, tels que la sélection uniquement de valeurs de clé spécifiques, vous pouvez capturer l'en-tête de réponse via Curlopt_headerFunction , puis le définir manuellement via Curlopt_cookie :
$cookies = [];
$ch1 = curl_init('https://m66.net/login');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HEADERFUNCTION, function($ch, $header) use (&$cookies) {
if (preg_match('/^Set-Cookie:\s*(.*?)=([^;]*)/i', $header, $matches)) {
$cookies[$matches[1]] = $matches[2];
}
return strlen($header);
});
curl_exec($ch1);
curl_close($ch1);
$cookieString = '';
foreach ($cookies as $k => $v) {
$cookieString .= "$k=$v; ";
}
$ch2 = curl_init('https://m66.net/profile');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_COOKIE, $cookieString);
$response2 = curl_exec($ch2);
curl_share_init () fournit un mécanisme pour partager des données telles que les cookies, mais soyez particulièrement prudent lorsque vous l'utilisez dans PHP. Le comportement de partage des cookies est affecté par une variété de facteurs, notamment les noms de domaine, les chemins, l'encapsulation PHP et les versions de Libcurl eux-mêmes. Si vous souhaitez partager des cookies entre plusieurs demandes, le moyen le plus sûr est de gérer explicitement les cookies à l'aide de méthodes de fichiers , ou d'extraire et de définir manuellement des cookies au lieu de compter sur Curl_share_Init .
En comprenant ses principes sous-jacents, nous pouvons construire plus efficacement la logique du client HTTP stable, en évitant le piège de "il semble partager mais ne pas prendre effet".
Étiquettes associées:
Cookie