🐘
PHP8にアプデしたらcurl_setoptのCURLOPT_COOKIEJARでCookieを保存できなくなった時の対処法
事象
php8以前では、curl_setopt関数でCURLOPT_COOKIEJARのオプションをセットして、cookieを保存できていたができなくなった。
file_existを実行するとファイルの存在は確認できるが、中身が空の状態。
結論
CURLプロセスを終了するときに、curl_close($ch)
ではなく、unset($ch)
を使う。
原因
COOKIEJARによるCookieの保存は、CURLプロセスが終了した時に書き込まれるが、PHP8からCURLプロセスの終了方法が変わっていました。より正確に言うと、curl_init()
の返り値が変わったようです。
変更履歴 ¶
バージョン 説明
8.0.0 成功時に、この関数は CurlHandle クラスのインスタンスを返すようになりました。 これより前のバージョンでは、resource を返していました。
この変更により、curl_close($ch)
ではCURLプロセスが終了できなくなりました。PHPのドキュメントのcurl_close
の説明には
注記:
この機能は効果がありません。PHP 8.0.0 より前では、この関数はリソースを閉じるために使用されていました。
そのため、プロセスを終了させるのにunset($ch)
を使用するとCookieが保存されるようになりました。
サンプルコード
// 一時フォルダにCookie保存するためのパスを定義
$cookieFile = tempnam(sys_get_temp_dir(),"cookie_test_");
// cURLのオプション設定と実行
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$output = curl_exec($ch);
// curl_close($ch); これをunset()に変える
unset($ch);
var_dump(file($cookieFile));
※ COOKIEJAR以外のオプションは適当です。
参考
Discussion