— PHP 8.6 —

PHP 8.6 で変わること
― リリース前のまとめ

公開日

PHP 8.6 が、2026年11月19日にリリースされる予定です。

新しい書き方がいくつか増えます。
それより大事なのは、保守しているサイトに影響しそうな変更です。

それぞれ「なぜ変わったのか」と一緒にまとめました。

⚠ リリース前の情報です。2026年11月11日の時点で、正式版はまだ出ていません。正式版が出たら、この記事も見直します。

先に結論

新しく書けるようになること

部分適用(引数の一部だけを先に決める)

関数を呼ぶときに、引数の一部を ? にしておくと、残りの引数を受け取る関数ができます。

文字で書くと分かりにくいので、コードで見たほうが早いです。

// これまで:型まで全部書き直す必要があった
$result = array_map(
    static fn(string $s): string => str_replace('hello', 'hi', $s),
    $arr
);

// PHP 8.6
$result = array_map(str_replace('hello', 'hi', ?), $arr);

? は「ここに1つ入る」、... は「残り全部」という意味です。

背景アロー関数(fn)で書くと、元の関数の引数の型や名前を、もう一度書き写すことになります。書く人にも読む人にも、ただの手間でした。PHP 8.1 で入った strlen(...) のような書き方(第一級callable)の延長で、PHP 8.5 で入ったパイプ演算子(|>)と組み合わせやすくする狙いもあります。

clamp()(値を範囲に収める)

値が範囲の外なら、近いほうの端に寄せて返す関数です。

// これまで
$percent = max(0, min(100, $value));

// PHP 8.6
$percent = clamp($value, min: 0, max: 100);

min が max より大きいときは、エラー(ValueError)になります。

背景これまでは min() と max() を組み合わせるか、フレームワークの関数を使うのが普通でした。min と max を逆に書いても気づけない、という弱点もありました。ほかの多くの言語には、もともと同じ関数があります。

Time\Duration(時間の長さを表すクラス)

「1分30秒」のような時間の長さを、ナノ秒の精度で表せるクラスです。

$timeout = \Time\Duration::fromMinutes(1)
    ->add(\Time\Duration::fromSeconds(30));   // 1分30秒

背景PHP の関数は、時間を「秒の int」「マイクロ秒の int」「秒の float」など、ばらばらの形で受け取っていました。日付の間隔を表す DateInterval は、月や日を含むので、タイムアウトのような「きっちり何秒」には向いていませんでした。

※ 「sleep() に Duration を渡せる」と紹介している記事もありますが、RFC では仮の例です。今回、今までの関数が Duration を受け取れるようになるわけではありません(新しい Polling API だけが受け取ります)。

readonly のプロパティに初期値を付けられる

final class Yen
{
    public readonly string $code = 'JPY';   // PHP 8.5 まではエラー
}

背景readonly が入ったとき、初期値は「定数と同じで、意味がない」とされて禁止されていました。PHP 8.4 でインターフェースにプロパティを書けるようになり、「実装するクラスごとに決まった値を持たせる」使い道ができたので、解禁されました。

SortDirection(並び順を表す enum)

$query->orderBy('created_at', SortDirection::Descending);

背景並び順は、SORT_ASC、'ASC' という文字、true / false など、場所によって書き方がばらばらでした。フレームワークもそれぞれ自分で作っていたので、PHP 本体に1つ用意して、そろえやすくしました。

そのほか

保守しているサイトで気をつけること

セッションの Cookie の初期値が、安全な側に変わる

いちばん影響がありそうなのが、ここです。

session.use_strict_mode0 → 1(知らないセッション ID を受け付けない)
session.cookie_httponly0 → 1(JavaScript からセッションの Cookie を読めない)
session.cookie_samesiteなし → Lax(ほかのサイトからの POST では Cookie を送らない)

背景3つとも、セキュリティの攻撃(セッションの乗っ取り・XSS・CSRF)を防ぐための設定です。Django、ASP.NET、Laravel、Symfony などは、もともと安全な側が初期値です。PHP 本体は、ずっと古い初期値のままでした。

注意したいのは、ほかのサイトから POST で戻ってくる仕組みです。

たとえば、決済や外部のログインのページから、POST でサイトに戻ってくる作りだと、セッションの Cookie が送られず、ログインや入力の途中の状態が消えることがあります。

JavaScript でセッションの Cookie を読んでいる作りも、読めなくなります。

※ これは php.ini に何も書いていないときの値です。レンタルサーバーの php.ini や、プログラムの中で値を指定していれば、そちらが使われます。

非推奨になる主な書き方

非推奨は、すぐに動かなくなるわけではありません。

警告(Deprecated)が出るようになり、PHP 9 でなくなる予定のものです。

よく出てきそうなものから、書き換え方と一緒に並べます。

① mb_ereg 系 → preg_*

日本のサイトで、いちばん気をつけたいものです。日本語の正規表現のために、昔から使われてきた関数なので、古いサイトほど残っています。

区切りの / と、日本語を正しく扱うための u を付けて書き換えます。

// 非推奨(全角・半角のスペースを1つにまとめる)
$name = mb_ereg_replace('[ \s]+', ' ', $name);

// 書き換え
$name = preg_replace('/[ \s]+/u', ' ', $name);

背景mb_ereg 系が中で使っている正規表現のライブラリ(Oniguruma)の開発が、2025年4月に終わったためです。

② finally の中の return

try で起きた例外が消えて、何もなかったように値が返ってしまいます。finally は後片づけだけにして、return は外に出します。

// 非推奨:保存に失敗しても、例外が消えて 'OK' が返る
function save(): string
{
    try {
        throw new RuntimeException('保存に失敗');
    } finally {
        return 'OK';
    }
}

// 書き換え
function save(): string
{
    try {
        $result = write();
    } finally {
        unlock();
    }
    return $result;
}

背景エラーも警告も出ないまま失敗が消えるので、あとで原因をたどれなくなるためです。よく使われているライブラリの中にも、実際に例外を消してしまう書き方が見つかったそうです。

③ 型を調べる関数の別名

// 非推奨(右が書き換え)
is_double($price);    // → is_float($price)
is_integer($count);   // → is_int($count)
is_long($count);      // → is_int($count)
doubleval($input);    // → floatval($input)

背景同じ働きの関数に、名前が2つあってややこしいためです。

④ spl_object_hash() → spl_object_id()

返ってくる値が、文字列から整数に変わります。値を保存したり、文字列として比べたりしている場合は注意します。

// 非推奨(32文字の文字列が返る)
$key = spl_object_hash($user);

// 書き換え(整数が返る)
$key = spl_object_id($user);

背景「hash」という名前なのに、オブジェクトの中身から作った値ではないためです。

⑤ そのほか

動きが変わるもの

サポートの期限

PHP 8.2セキュリティの修正は 2026年12月31日で終了
PHP 8.3セキュリティの修正は 2027年末まで
PHP 8.4不具合の修正は 2026年末まで。セキュリティの修正は 2028年末まで
PHP 8.5不具合の修正は 2027年末まで。セキュリティの修正は 2029年末まで
PHP 8.6決まりどおりなら、不具合の修正は 2028年末まで。セキュリティの修正は 2030年末まで

※ PHP の公式サイトの予定です。8.6 は、まだ表に載っていないので、「リリースから2年は不具合の修正、その後2年はセキュリティの修正」という決まりから出した日付です。

8.2 のまま動いているサイトは、あと1か月半で、脆弱性が見つかっても直してもらえなくなります。

8.6 を待つより、まず 8.2 から上げるほうが先です。

このサイトの場合

このサイトの PHP は 8.4 です(8.4 に上げたときの話)。

念のため、今のコードを調べました。

8.6 は、使っているレンタルサーバーで選べるようになってから、手元の環境で確かめて上げる予定です。

思うこと

新機能より、古いものの片づけのほうが多いバージョンです。

しかも、その一つひとつに「なぜやめるのか」がきちんと書いてあります。

理由が分かっていると、保守しているサイトを直すときも、お客様に説明するときも、ぐっと楽になります。

参考

使った技術

調べたもの
php-src の UPGRADING(PHP-8.6 ブランチ)PHP の RFCphp.net の Supported Versions
このサイトの確認
PHP 8.4grep(非推奨の書き方の検索)