PHP가 CURL을 사용하여 여러 HTTP 요청을 수행 할 때 쿠키, DNS 캐시 또는 SSL 세션과 같은 여러 요청간에 특정 데이터를 공유하는 경우가 있습니다. 현재 Curl_share_init () 및 관련 기능을 사용하여 공유를 달성 할 수 있습니다. 그러나 많은 개발자들은이 기능을 사용하려고 할 때 일반적인 문제를 겪습니다.이 기사에서는이 문제의 원인과 솔루션을 자세히 분석합니다.
먼저 Curl_share_init을 사용하여 쿠키를 공유하는 방법을 빠르게 검토합시다.
$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);
// 이 요청이 설정 될 것이라고 가정하십시오 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);
// 마지막으로 요청 된 설정을 여기에서 보내기를 바랍니다. Cookie
$response2 = curl_exec($ch2);
curl_close($ch1);
curl_close($ch2);
curl_share_close($sh);
코드의 논리에서, 우리는 curl_share_setopt () 의 curl_lock_data_cookie 를 통해 쿠키의 공유를 실현할 것으로 예상됩니다. 그러나 많은 개발자들은 두 번째 요청이 첫 번째 요청에 의해 쿠키를 반환 한 상태에서 나오지 않는다고 보고했습니다.
공유 쿠키를 설정했지만 Libcurl은 설정하지 않는 한 기본적으로 쿠키를 자동으로 저장하거나 작성하지 않습니다.
curlopt_cookiefile : 기존 쿠키 파일을 읽으십시오
curlopt_cookiejar : 요청 후 쿠키 파일을 작성하십시오
'' (빈 문자열)로 설정하면 메모리 쿠키 처리가 가능하지만 Curl_share_* 와 결합하면이 방법이 불안정 할 수 있습니다.
PHP의 컬 확장은 Libcurl 라이브러리를 사용합니다. 일부 플랫폼이나 버전에서 Curl_share_*의 동작은 공식 문서 설명, 특히 쿠키와 관련된 부분과 약간 다를 수 있습니다. Curl_Lock_Data_Cookie 는 낮은 수준의 libcurl 에서 사용하도록 설계되었으며, PHP 이후의 호출 방법은 일관되지 않게 지원됩니다.
쿠키에는 경로 (경로) 및 도메인 (도메인) 제한이 있습니다. 요청 된 URL 도메인 이름이 다른 경우 (하위 도메인 이름이 다르더라도) 쿠키는 전송되지 않습니다. 마찬가지로 서버에서 설정 한 쿠키가 특정 경로에 대해서만 유효하고 다음 요청 된 경로가 포함되지 않은 경우 쿠키는 자동으로 첨부되지 않습니다.
명시 적 관리를 위해 임시 쿠키 파일을 사용하는 것이 가장 쉽고 신뢰할 수있는 방법입니다.
$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);
이 방법은 curl_share_* 에 의존하지 않으며 쿠키를 저장 및 다시로드 할 수 있으며 대부분의 PHP 프로젝트에 적합합니다.
특정 키 값 만 선택하는 등 쿠키를보다 신중하게 제어 해야하는 경우 Curlopt_headerFunction을 통해 응답 헤더를 캡처 한 다음 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 ()는 쿠키와 같은 데이터를 공유하는 메커니즘을 제공하지만 PHP에서 사용할 때 특히주의하십시오. 쿠키의 공유 동작은 도메인 이름, 경로, PHP 캡슐화 및 libcurl 자체 버전을 포함한 다양한 요인에 의해 영향을받습니다. 여러 요청간에 쿠키를 공유하려면 파일 방법을 사용하여 쿠키를 명시 적으로 관리하거나 Curl_share_init 에 의존하는 대신 쿠키를 수동으로 추출하고 설정하는 것입니다 .
기본 원칙을 이해함으로써 우리는 "공유되는 것처럼 보이지만 실제로는 효력을 발휘하지 않는 것 같다"는 함정을 피하면서 안정적인 HTTP 클라이언트 로직을보다 효과적으로 구축 할 수 있습니다.