update page now
Laravel Live Japan
2025/11/20 リリース

より賢く、より速く。未来へ向けて。

PHP 8.5 は、PHP 言語のメジャーアップデートですURI 拡張モジュールパイプ演算子クローン時のプロパティ変更機能などの新機能が含まれています。

PHP 8.5 の主な機能

より速くよりクリーンに。そして開発者のために

URI 拡張モジュール

URL のパース、正規化、処理を行う新しい組み込みの URI 拡張モジュールが PHP 8.5 で追加されました。

パイプ演算子

|> 演算子を使うと callable を左から右にチェインさせ、中間変数を使わずに値を複数の関数にスムーズに受け渡せます。

Clone With

新しい clone() 構文でオブジェクトを clone してプロパティを更新します。readonly クラスの "with-er" パターンが簡潔になります。

#[\NoDiscard] アトリビュート

#[\NoDiscard] アトリビュートを使うと、戻り値が利用されていない場合に警告を出します。ミスを防ぎ全体の API 安全性を向上するのに役立ちます。

定数式でのクロージャと第一級 callable

static なクロージャと第一級 callable が、アトリビュートの引数などの定数式で使えるようになります。

持続的な cURL 共有ハンドル

ハンドルを複数の PHP リクエストにまたがって持続させられるようになります。同じホストへの接続初期化を繰り返すコストを避けることができます。

URI 拡張モジュール

常に有効な新しい URI 拡張モジュールは、RFC 3986 と WHATWG URL 標準にしたがって URI や URL を安全にパース・編集できる API を提供します。

uriparser (RFC 3986) と Lexbor (WHATWG URL) ライブラリを利用しています。

この機能の背景は PHP Foundation のブログをお読みください。

PHP 8.4 以前
$components = parse_url('https://php.net/releases/8.4/en.php');

var_dump($components['host']);
// string(7) "php.net"
PHP 8.5 NEW RFC
use Uri\Rfc3986\Uri;

$uri = new Uri('https://php.net/releases/8.5/en.php');

var_dump($uri->getHost());
// string(7) "php.net"

パイプ演算子

パイプ演算子を使うと、中間変数を扱うことなく複数の関数呼び出しを繋げることができます。これによってたくさんの「入れ子呼び出し」を置き換え、中から外ではなく先に向かって読むことができるようになります。

この機能の背景について詳しくは PHP Foundation のブログをお読みください。

PHP 8.4 以前
$title = ' PHP 8.5 Released ';

$slug = strtolower(
    str_replace('.', '',
        str_replace(' ', '-',
            trim($title)
        )
    )
);

var_dump($slug);
// string(15) "php-85-released"
PHP 8.5 NEW RFC
$title = ' PHP 8.5 Released ';

$slug = $title
    |> trim(...)
    |> (fn($str) => str_replace(' ', '-', $str))
    |> (fn($str) => str_replace('.', '', $str))
    |> strtolower(...);

var_dump($slug);
// string(15) "php-85-released"

Clone With

clone() 関数に連想配列を渡すことで、オブジェクトのクローン時にプロパティを更新することができるようになります。これによって、readonly クラスの "with-er" パターンを簡単に実装することができるようになります。

PHP 8.4 以前
readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}

    public function withAlpha(int $alpha): self
    {
        $values = get_object_vars($this);
        $values['alpha'] = $alpha;

        return new self(...$values);
    }
}

$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);
PHP 8.5 NEW RFC
readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}

    public function withAlpha(int $alpha): self
    {
        return clone($this, [
            'alpha' => $alpha,
        ]);
    }
}

$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);

#[\NoDiscard] アトリビュート

#[\NoDiscard] アトリビュートを関数に追加すると、戻り値が利用されたかを PHP がチェックし、されていなければ警告を出します。これにより、戻り値が重要なのにそれを利用することをうっかり忘れやすい API の安全性を高めることができます。

関連する (void) キャストを使うと、戻り値を使っていないのが意図的であることを明示できます。

PHP 8.4 以前
function getPhpVersion(): string
{
    return 'PHP 8.4';
}

getPhpVersion(); // No warning
PHP 8.5 NEW RFC
#[\NoDiscard]
function getPhpVersion(): string
{
    return 'PHP 8.5';
}

getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void)

定数式でのクロージャと第一級 callable

static なクロージャと第一級 callable が定数式で利用できるようになります。これはアトリビュートの引数、プロパティやパラメータのデフォルト値、定数を含みます。

PHP 8.4 以前
final class PostsController
{
    #[AccessControl(
        new Expression('request.user === post.getAuthor()'),
    )]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}
PHP 8.5 NEW RFC RFC
final class PostsController
{
    #[AccessControl(static function (
        Request $request,
        Post $post,
    ): bool {
        return $request->user === $post->getAuthor();
    })]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}

持続的な cURL 共有ハンドル

curl_share_init() と違い、curl_share_init_persistent() で作られたハンドルは PHP のリクエスト終了時に破棄されません。もし同じオプションが設定された持続的な共有ハンドルが存在すればそれが再利用されるため、cURL ハンドルを毎回初期化するコストを避けることができます。

PHP 8.4 以前
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);

curl_exec($ch);
PHP 8.5 NEW RFC RFC
$sh = curl_share_init_persistent([
    CURL_LOCK_DATA_DNS,
    CURL_LOCK_DATA_CONNECT,
]);

$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);

// This may now reuse the connection from an earlier SAPI request
curl_exec($ch);

array_first() ・ array_last() 関数

array_first()array_last() 関数は、それぞれ配列の最初と最後の値を返します。空配列の場合は null を返します(そのため ?? 演算子と組み合わせやすいです)。

PHP 8.4 以前
$lastEvent = $events === []
    ? null
    : $events[array_key_last($events)];
PHP 8.5 NEW RFC
$lastEvent = array_last($events);

その他の新機能・改善

  • Fatal エラー(実行時間の最大値の超過など)にバックトレースが含まれるようになります。
  • アトリビュートが定数を対象にすることができるようになります。
  • #[\Override] アトリビュートをプロパティに適用できるようになります。
  • #[\Deprecated] アトリビュートをトレイトと定数に使用できるようになります。
  • static プロパティで非対称可視性を利用できるようになります。
  • コンストラクタのプロモーションで、プロパティを final にすることができるようになります。
  • 無名関数の再帰を簡単に行うための Closure::getCurrent() メソッドが追加されました。
  • 関数 setcookie()setrawcookie() で "partitioned" キーが利用できます。
  • get_error_handler()get_exception_handler() 関数が追加されました。
  • Dom\Element::getElementsByClassName()Dom\Element::insertAdjacentHTML() メソッドが追加されました。
  • grapheme_levenshtein() 関数が追加されました。
  • PHP コアと拡張モジュールのアトリビュートを不正なターゲットに利用したときに発生するコンパイル時エラーを抑制する #[\DelayedTargetValidation] アトリビュートが追加されました。

推奨されなくなる機能・下位互換性のない変更

  • shell_exec() のエイリアスとして使われているバッククォート演算子は非推奨になりました。
  • 正規化されていない型名 (boolean), (integer), (double), (binary) でのキャストは非推奨になりました。 代わりにそれぞれ (bool), (int), (float), (string) を使ってください。
  • さまざまな PHP エンジンの想定を壊してしまうため、disable_classes INI ディレクティブは削除されました。
  • case 文の末尾にコロンではなくセミコロンを使うことは非推奨になりました。
  • 配列のオフセットや array_key_exists() の引数に null を使うことは推奨されなくなりました。代わりに空文字列を使ってください。
  • class_alias() でクラス名のエイリアスに "array" と "callable" を使うことはできなくなりました。
  • マジックメソッド __sleep()__wakeup() は soft-deprecated になりました。代わりに __serialize()__unserialize() を使ってください。
  • NAN を他の型にキャストすると警告が出るようになりました。
  • 配列ではない値(null を除く)を []list() で分解すると警告が出るようになりました。
  • float(または数値形式の文字列)を int にキャストする際、その値を int として表現できない場合に警告が出るようになりました。
To Top