0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHP 8.5で curl_close() と $http_response_header が deprecated になった — 警告の意味と移行方法

0
Posted at

結論(先に解決策)

PHP 8.5 に上げたら、HTTP クライアント周りでこの2つの Deprecated 警告が出ることがあります。

Deprecated: Function curl_close() is deprecated
Deprecated: The $http_response_header variable is deprecated since 8.5

どちらも機能は今も動く(即エラーではない)ので、慌てず次のように移行します。

非推奨 対応
curl_close($ch) 呼び出しを削除するだけ(PHP 8.0+ で既に no-op)
$http_response_header http_get_last_response_headers() を使う(PHP 8.5+)。8.4 以前はフォールバック
// curl_close は消すだけ
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
// curl_close($ch);   ← 削除。CurlHandle は GC が破棄する

// $http_response_header は関数経由に
$body = file_get_contents($url);
$headers = function_exists('http_get_last_response_headers')
    ? http_get_last_response_headers()   // PHP 8.5+
    : ($http_response_header ?? []);     // 8.4 以前のフォールバック

症状

PHP 8.5 で、これまで普通に書いていたコードに Deprecated 警告が付く。

// (1) cURL を閉じる定番コード
curl_close($ch);
// Deprecated: Function curl_close() is deprecated

// (2) file_get_contents / fopen 後にレスポンスヘッダを読む定番コード
$body = file_get_contents('https://example.com/');
var_dump($http_response_header);
// Deprecated: The $http_response_header variable is deprecated since 8.5

error_reportingE_DEPRECATED を出している環境(開発機や display_errors=On の本番)でログが警告まみれになる、というのが実害です。


原因

curl_close() — そもそも何もしていない関数になっていた

PHP 8.0 で cURL ハンドルが リソースから CurlHandle オブジェクトに変わりました。オブジェクトは参照が無くなれば GC(ガベージコレクション)が自動で破棄するため、curl_close()8.0 時点で実質 no-op(何もしない) になっていました。

「もう不要な関数」なので、8.5 で正式に deprecated 化された、という流れです。mysqli 等と違い、明示クローズは要りません。

$http_response_header — マジック変数の廃止方針

$http_response_header は、file_get_contents() などのストリーム経由 HTTP アクセスのレスポンスヘッダ呼び出したローカルスコープに自動で生える特殊な変数でした。

function fetch($url) {
    $body = file_get_contents($url);
    return $http_response_header;   // どこで定義した? → PHP が勝手に注入していた
}

この「暗黙的に変数が出現する」挙動は、スコープの見通しが悪く静的解析も難しいため、PHP は関数で明示的に取得する方式http_get_last_response_headers())へ移行することにし、マジック変数を deprecated にしました。


解決

1. curl_close() は削除する

置き換えではなく削除でOKです。残してもいい挙動はしますが、警告を消すなら消すのが正解。

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 10,
]);
$body   = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
// 明示クローズ不要。$ch がスコープを抜ければ破棄される

ハンドルを早く解放したいなら unset($ch) で参照を切れば十分です。

2. $http_response_header はバージョン分岐で吸収する

8.5 と 8.4 以前の両方をサポートするなら、関数の有無で分岐します。ライブラリのように複数環境で動かすコードでは特に有効です。

function http_get(string $url): array {
    $body = @file_get_contents($url);

    if (function_exists('http_get_last_response_headers')) {
        $headers = http_get_last_response_headers();   // PHP 8.5+
    } else {
        $headers = $http_response_header ?? [];        // PHP 8.4 以前
    }

    return ['body' => $body, 'headers' => $headers];
}

http_get_last_response_headers()直近の HTTP ストリームアクセスのヘッダを返すので、file_get_contents()直後に呼ぶのは従来と同じです。


補足

  • どちらも 8.5 ではまだ動く(Deprecated であって Removed ではない)ので、急いで全部直す必要はありません。ただし E_DEPRECATED がログを汚すので、アップグレード時にまとめて潰しておくと後が楽です。
  • $http_response_header を多用しているなら、この機会に cURL か Guzzle 等の HTTP クライアントへ寄せるのも検討に値します。ヘッダ取得が明示的になり、バージョン分岐も不要になります。
  • 要点は curl_close は消す、$http_response_headerhttp_get_last_response_headers() に(8.4 以前はフォールバック)」
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?