Wenn PHP Curl verwendet, um mehrere HTTP -Anforderungen durchzuführen, möchten wir manchmal bestimmte Daten zwischen mehreren Anforderungen wie Cookies, DNS -Caches oder SSL -Sitzungen weitergeben. Zu diesem Zeitpunkt können Sie curl_share_init () und verwandte Funktionen verwenden, um die Freigabe zu erreichen. Viele Entwickler stoßen jedoch auf ein gemeinsames Problem, wenn Sie versuchen, die Funktion zu verwenden: Dieser Artikel analysiert die Ursachen und Lösungen dieses Problems im Detail.
Lassen Sie uns zunächst schnell überprüfen, wie Sie curl_share_init verwenden, um Cookies zu teilen:
$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);
// Angenommen, diese Anfrage wird festgelegt 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);
// Ich hoffe, dies sendet hier die zuletzt angeforderten Einstellungen Cookie
$response2 = curl_exec($ch2);
curl_close($ch1);
curl_close($ch2);
curl_share_close($sh);
Aus der Logik des Codes erwarten wir, dass die Freigabe von Cookies über curl_lock_data_cookie von curl_share_setopt () realisiert wird. Viele Entwickler haben jedoch berichtet, dass die zweite Anfrage nicht mit dem von der ersten Anfrage zurückgegebenen Cookie geliefert wird .
Obwohl wir freigegebene Cookies festlegen, speichert oder schreiben Sie nicht automatisch Cookies, es sei denn, es ist festgelegt:
Curlopt_Cookiefile : Lesen Sie vorhandene Cookie -Dateien
Curlopt_cookiejar : Schreiben Sie eine Cookie -Datei nach Anfrage
Eingestellt auf '' (leere Zeichenfolge) kann die In-Memory-Cookie-Verarbeitung aktivieren, aber diese Methode kann in Kombination mit curl_share_* instabil sein.
Die Curl -Erweiterung von PHP verwendet die Bibliothek Libcurl . Auf einigen Plattformen oder Versionen kann das Verhalten von Curl_Share_* geringfügig von der offiziellen Dokumentationsbeschreibung, insbesondere den Teilen mit Cookies, unterscheiden. CURL_LOCK_DATA_COOKIE ist mehr für die Verwendung durch libcurl ausgelegt, während die Aufrufmethode nach dem inkonsistent eingekapselten Aufrufmethode es unterstützt.
Cookies haben Pfad- (Pfad-) und Domänen- (Domänen-) Einschränkungen. Wenn der angeforderte URL -Domain -Name unterschiedlich ist (auch wenn der Subdomet -Name unterschiedlich ist), wird der Cookie nicht gesendet. Wenn der vom Server festgelegte Cookie nur für einen bestimmten Pfad gültig ist und der nächste angeforderte Pfad nicht enthalten ist, wird das Cookie nicht automatisch angehängt.
Die Verwendung von temporären Cookie -Dateien für explizite Verwaltung ist der einfachste und zuverlässigste Weg.
$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);
Diese Methode beruht nicht auf curl_share_* und stellt sicher, dass Cookies gespeichert und neu geladen werden können und für die meisten PHP -Projekte geeignet ist.
Wenn Sie Cookies sorgfältiger steuern müssen, z. B. nur spezifische Schlüsselwerte, können Sie den Antwortheader über Curlopt_headerfunction erfassen und dann manuell durch curlopt_cookie einstellen:
$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 () bietet einen Mechanismus zum Austausch von Daten wie Cookies, aber seien Sie besonders vorsichtig, wenn Sie sie in PHP verwenden. Das gemeinsame Verhalten von Cookies wird von einer Vielzahl von Faktoren beeinflusst, einschließlich Domänennamen, Pfaden, PHP -Kapselung und Versionen von libcurl selbst. Wenn Sie Cookies zwischen mehreren Anfragen freigeben möchten, besteht die sicherste Möglichkeit, Cookies mithilfe von Dateimethoden explizit zu verwalten oder Cookies manuell zu extrahieren und manuell zu extrahieren und zu setzen, anstatt sich auf curl_share_init zu stützen.
Durch das Verständnis der zugrunde liegenden Prinzipien können wir eine stabile HTTP -Client -Logik effektiver erstellen und die Falle von "es scheint, dass sie geteilt, aber tatsächlich nicht wirksam wird".