32
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHPAdvent Calendar 2024

Day 2

【PHP8.4】PHP8.4がリリースされたので新機能全部やる

Last updated at Posted at 2024-12-01

PHP8.4 / PHP8.3 / PHP8.2 / PHP8.1

2024/11/24にPHP8.4がリリースされました
大きな新機能については、PHP8.0以降公開されるようになったランディングページで見ることができます。
またマイグレーションガイドも存在します。

採用されたRFCについてはPHP8.4の新機能でまとめています。

ここでは、概要だけではなくUPGRADINGに載っている全ての変更点を全部見て回ることにします。

Backward Incompatible Changes

下位互換性のない変更点。

Core

The type of PHP_DEBUG and PHP_ZTS constants changed to bool.

定数PHP_DEBUGとPHP_ZTSがbool型になりました。
PHP8.3まではint型でした。

The name of uploaded files and files created by the tempnam() function are now 13 bytes longer

アップロードされたファイル、およびtempnamで作られるファイル名の長さが13バイト長くなりました。
とあるのですが手元で試したら54bEA6C.tmpってかんじで変わってませんでした。
Windowsでは効かないようです。

Encountering recursion during comparison now results in a Error exception, rather than a fatal error.

比較中に再帰ループに入ったらFatal Errorになっていたのが例外になりました。

1 === hoge();
function hoge(){
    return hoge();
}

とあるのですが、↑の例はAllowed memory size exhaustedのFatal Errorになりました。
この使い方ではないということなのか?

Indirect modification of readonly properties within __clone() is no longer allowed

__clone()中にreadonlyプロパティの間接的な書き換えができなくなりました。

PHP8.3で__clone()中にreadonlyプロパティを書き替えできるようになったのですが、リファレンスから書き替えできないように制限を入れるようです。

class Foo {
    public function __construct(public readonly DateTime $bar){}

    public function __clone()
    {
        $ref = &$this->bar;
        $ref->modify('+1 year');
    }
}

$foo = new Foo(new DateTime());
$foo2 = clone $foo;
var_dump($foo);

と思ったんだけどなんかこれ普通に動きました。
"Indirect modification"ってどういうことなんだろう?

The exit (and die) language constructs now behave more like a function.

exit()は言語構造から普通の関数になりました

'exit'();

// PHP8.4 エラー出ない
// PHP8.3 Fatal error: Uncaught Error: Call to undefined function exit()

これまでの言語構造exit;も当面は使用可能です。

The E_STRICT constant was deprecated and its corresponding error level was removed.

定数E_STRICT非推奨になりました。
この警告は主にPHP5時代の古い書き方をどうにかするためのものだったのですが、その後E_WARININGや例外に置き換えられてPHP8になったころにはほぼなくなっていたので、役割は終わりました。

Extension Class constants are now typed

以下エクステンションのクラス定数に型が付きました。
・Date
・Intl
・PDO
・Reflection
・SPL
・Sqlite
・XMLReader

echo new ReflectionClassConstant('PDO', 'PARAM_BOOL')->getType(); // int

むしろ型がついていないクラス定数ってあるのか?

Resource to Object conversions

以下のいくつかの関数が、これまでリソースを返していたのがオブジェクトを返すようになりました。
PHPは8.0あたりから、リソースを滅ぼすべく動いています

この変更は互換性を重視しており、is_resource()でのチェックこそ引っかかってしまいますが、それ以外はそのままで動くようになっています。

dba_open()dba_popen()
odbc_connectodbc_pconnectおよび類似の関数。
SoapClient::$httpurlと`SoapClient::$sdl

New warnings and exceptions

新たな警告と例外。

curl_multi_select throws a ValueError if the timeout argument if it's negative or greater than PHP_INT_MAX

curl_multi_selectは引数$timeoutにマイナス値やPHP_INT_MAX以上を渡されるとValueErrorを出すようになりました。

imagejpeg/imagewebp/imagepng/imageavif throws an exception if an invalid quality parameter value is passed.

imagejpeg/imagewebp/imagepng/imageavifは引数として無効な値を渡されたときに例外を出すようになりました。

imagescale throws an exception if the width/height argument underflows/overflows or

imagescaleは引数として範囲外の値を渡されたときに例外を出すようになりました。

bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception if the domain argument is empty

bind_textdomain_codesetは引数$domainが空だと例外を出すようになりました。

resourcebundle_get(), ResourceBundle::get(), and accessing offsets on a ResourceBundle object now throw

ResourceBundle::getおよびResourceBundleオブジェクトは、不正な型にTypeError、不正な値にValueErrorを出すようになりました。

IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.

IntlDateFormatter::__constructは引数$localeが不正な場合に例外を出すようになりました。

NumberFormatter::__construct() throws a ValueError if the locale is invalid

NumberFormatter::__constructは引数$localeが不正な場合に例外を出すようになりました。

mb_encode_numericentity() and mb_decode_numericentity() now check that the $map is only composed of integers

mb_encode_numericentitymb_decode_numericentityの引数$mapは整数値以外にValueErrorを出すようになりました。

mb_http_input() now always throws a ValueError if the $type is invalid

mb_http_inputは引数$typeが不正な場合に例外を出すようになりました。

mb_http_output() now checks that the $encoding parameter does not contain any null bytes

mb_http_outputは引数$encodingをヌルバイトチェックするようになりました。

odbc_fetch_row() now emits a warning when a value less than or equal to 0 is passed for parameter $row

odbc_fetch_rowは引数$rowに0以下を渡すと警告を出すようになりました。

The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and pcntl_sigtimedwait() now throw

pcntl_sigprocmaskpcntl_sigwaitinfopcntl_sigtimedwaitは引数$signalsが不正な場合に例外を出すようになりました。

Calling simplexml_import_dom() with a non-XML object now throws a TypeError instead of a ValueError

simplexml_import_domは引数$nodeにDOM以外を渡した場合に、これまでValueErrorを出していたのがTypeErrorを出すようになりました。

round() now validates the value of the $mode parameter and throws a ValueError for invalid modes

roundは引数$modeが不正な場合に、これまではPHP_ROUND_HALF_UPとみなしていたのが例外を出すようになりました。

The str_getcsv() function now throws ValueErrors

str_getcsvは引数$separator$enclosureが1バイトでない場合に例外を出すようになりました。
これによって動きがfgetcsvと揃いました。

php_uname() now throws ValueErrors if the $move parameter is invalid

php_unameは引数$modeが不正な場合に例外を出すようになりました。

The "allowed_classes" option for unserialize() now throws TypeErrors and ValueErrors

unserializeは引数$optionsのallowed_classesに正しくない値が入ってきたら例外を出すようになりました。

Passing an invalid character encoding to XMLReader::open() or XMLReader::XML() now throws a ValueError

XMLReader::openは引数$encodingが不正な場合に例外を出すようになりました。

XSLTProcessor::setParameter() will now throw a ValueError when its arguments contain null bytes

XSLTProcessor::setParameterはヌルバイトが入ってきたら例外を出すようになりました。

Calling XSLTProcessor::importStyleSheet() with a non-XML object now throws a TypeError instead of a ValueError

XSLTProcessor::importStyleSheetは引数$stylesheetがXMLオブジェクトでない場合に、これまでValueErrorを出していたのがTypeErrorを出すようになりました。

Failure to call a PHP function callback during evaluation now throws instead of emitting a warning

DOMXPath::registerPhpFunctions()においてコールバック関数の呼び出しに失敗した場合、これまでE_WARNINGを出していたのが例外になりました

DOM

Some DOM methods previously returned false or a PHP_ERR DOMException

DOMの幾つかのメソッドで、ノードを追加することに失敗するとこれまでfalseを返していたのがDOMExceptionを出すようになりました。
ただし、実際にこれが発生する可能性は非常に低く、影響はほぼありません。

Previously, DOMXPath objects could be cloned, but resulted in an unusable object

DOMXPathをcloneすると例外を出すようになりました。
これまではcloneされたように見えて実際は使用不能なオブジェクトができていました。

Removed DOMImplementation::getFeature()

DOMImplementation::getFeature()が削除されました。

GMP

The GMP class is now final and cannot be extended anymore

GMPfinalクラスになり、extendsできなくなりました。

MBString

On invalid strings (those with encoding errors), mb_substr() now interprets character indices in the same manner as most other mbstring functions

mb_substrは、不正な文字を渡された場合の文字数カウントを他のmbstring関数と揃えました。
すなわち、mb_strposの返り値をそのままmb_substrに渡せます。

For SJIS-Mac (MacJapanese) strings, character indices passed to mb_substr() now refer to the indices of the Unicode codepoints

SJIS-Macエンコーディングを使っている場合、mb_substr等に渡されるインデックスがUnicodeコードポイントのインデックスを参照するようになりました。

とあるんだけどMACじゃないのでよくわからない。

Mysqli

The unused and undocumented constant MYSQLI_SET_CHARSET_DIR has been removed

定数MYSQLI_SET_CHARSET_DIRが削除されました。
この定数は使用されておらず、ドキュメント化もされていませんでした。

The MYSQLI_STMT_ATTR_PREFETCH_ROWS constant has been removed

定数MYSQLI_STMT_ATTR_PREFETCH_ROWSが削除されました。
この定数はmysqlndでは使用できませんでした。

The MYSQLI_CURSOR_TYPE_FOR_UPDATE and MYSQLI_CURSOR_TYPE_SCROLLABLE constants have been removed

定数MYSQLI_CURSOR_TYPE_FOR_UPDATE・MYSQLI_CURSOR_TYPE_SCROLLABLEが削除されました。
この定数はmysqlndでもlibmysqlでも使用できませんでした。

The unused MYSQLI_TYPE_INTERVAL constant, which is currently a stub and an alias for MYSQLI_TYPE_ENUM, has been removed

定数MYSQLI_TYPE_INTERVAL・MYSQLI_TYPE_ENUMが削除されました。
MySQLにこれらの型が追加される予定は、いまのところありません。

MySQLnd

The error code reported for MySQL server wait timeouts has been changed from 2006 to 4031

MySQLサーバのバージョン8.0.24以降、サーバタイムアウトのエラーコードが2006から4031に変更になりました。

Opcache

The JIT config defaults changed

JITのINI設定値のデフォルトが、opcache.jit_buffer_size=0からopcache.jit_buffer_size=64M / opcache.jit=disableに変更されました。
これまでjit_buffer_size=0ならJIT無効と判断していたところを、状態を表すフラグで判断するようになり、見た目わかりやすくなりました。

The maximum value of the opcache.interned_strings_buffer setting on 64bit architectures is now 32767

opcache.interned_strings_bufferの最大値が4096から32767になりました。

If JIT is enabled, PHP will now exit with a fatal error on startup in case of JIT startup initialization issues

JITが有効な場合、JITの初期化に失敗するとPHPが致命的エラーを発生して終了します。

PCNTL

The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and pcntl_sigtimedwait() now always return false on failure

pcntl_sigprocmaskpcntl_sigwaitinfopcntl_sigtimedwaitは、失敗した場合に必ずfalseを返します。
以前は時折-1を返すことがありました。

PCRE

The bundled pcre2lib has been updated to version 10.44

バンドルされているpcre2libがバージョン10.44になりました。
結果、{,3}がテキストではなく量指定子になるなど、一部の正規表現の動作が変更されます。

PDO_DBLIB

setAttribute, DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER and DBLIB_ATTR_DATETIME_CONVERT have been changed to set value as a bool

PDO_DBLIBのsetAttributeに渡す定数DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIERとDBLIB_ATTR_DATETIME_CONVERTの型がboolになりました。

この定数ドキュメントに存在しないので詳細不明です。

PDO_FIREBIRD

Since some Firebird C++ APIs are used now, this extension requires a C++ compiler to be built

Firebirdは一部でC++ APIが使用されているため、ビルドにはC++コンパイラが必要です。

getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool

定数PDO::ATTR_AUTOCOMMITは値がintからboolになりました。

PDO_MYSQL

getAttribute, ATTR_AUTOCOMMIT, ATTR_EMULATE_PREPARES, MYSQL_ATTR_DIRECT_QUERY have been changed to get values as bool

定数PDO::ATTR_AUTOCOMMIT・PDO::ATTR_EMULATE_PREPARES・PDO::MYSQL_ATTR_DIRECT_QUERYの型がintからboolになりました。

PDO_PGSQL

The DSN's credentials, when set, are given priority over their PDO constructor counterparts

DSNの資格情報が、PDOコンストラクタの資格情報よりも優先されるようになります。

SimpleXML

Get methods called, or casting to a string on a SimpleXMLElement will no longer implicitly reset the iterator data

get系メソッドを呼んだり、SimpleXMLElementにキャストしたりしても内部ポインタがリセットされなくなりました。
これまではforeach()内でgetName()すると無限ループしていましたが、ループしなくなりました。

SOAP

SoapClient::$typemap is now an array rather than a resource

SoapClient::$typemapはリソースから配列になりました。

The SOAP extension gained an optional dependency on the session extension

SOAPエクステンションはセッションに依存するようになりました。
セッションエクステンションをロードせずにSOAPエクステンションを使うと起動時にエラーになります。

Standard

strcspn() with empty $characters now returns the length of the string instead of incorrectly stopping at the first NUL character

strcspnの引数$charactersに空文字を渡した場合、これまでヌルバイトで止まっていたのを文字列長を返すようになりました。

http_build_query() now correctly handles backed enums

http_build_queryは、Backed ENUMを正しく処理できるようになりました。

stream_bucket_make_writeable() and stream_bucket_new() will now return a StreamBucket instance instead of an instance of stdClass

stream_bucket_make_writeablestream_bucket_newは、これまでstdClassを返していたのをStreamBucketを返すようになりました。

Tidy

Failures in the constructor now throw exceptions rather than emitting warnings and having a broken object

Tidyコンストラクタで問題が起きた場合、今までは壊れたオブジェクトが返っていたのが例外が出るようになりました。

New Features

新機能。

Core

Added request_parse_body() function

関数request_parse_bodyが追加されました。
POST以外のHTTPメソッドではリクエストボディを取得するのが何気に面倒だったのですが、関数ひとつで取得できるようになります。

// REST ClientでPUTを送る
PUT https://test.localhost/sample.php HTTP/1.1
Content-Type: application/json

{
    "foo": "bar",
    "hoge": "fuga"
}

// PHPで取得
var_dump($_REQUEST); // [] 取れない
[$body, $files] = request_parse_body(); // [foo=>bar, hoge=>fuga]

むしろ今まで困難だったことに驚きですね。

Getting the debug info for WeakReference will now also output the object it references

WeakReferenceのデバッグ情報に、参照先も出力されるようになりました。

$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref);

// PHP8.4 object(WeakReference){ object=> object(stdClass)}
// PHP8.3 object(WeakReference){}

デバッグが楽になります。

The output of Closure::__debugInfo() now includes the name, file, and line of the Closure

Closure::__debugInfo()のデバッグ情報に、name・file・lineが出力されるようになりました。

$func = static function() { return 1; };
$closure = Closure::bind($func, null);
var_dump($closure);

// PHP8.4 object(Closure){ name=> path/to/name, file=>path/to/file, line=>2 }
// PHP8.3 object(Closure){}

デバッグが楽になります。

new expressions with constructor arguments are now dereferencable

コンストラクタにかぎって、全体を括弧で囲まなくてもメソッドを連鎖させることができるようになりました。

new HOGE()->run();   // PHP8.4以降OK
(new HOGE())->run(); // PHP8.3まで

たった2文字の差ですが、躓かず書けるようになるので便利ですね。

Added the #[\Deprecated] attribute

Deprecatedアトリビュートが追加されました。

#[\Deprecated]
function test() {}

test();
// PHP8.4 E_USER_DEPRECATED
// PHP8.3 何も起きない

廃止したい関数・メソッド・クラス定数を楽に明記できるようになります。
PHP8.3以前ではただのコメントなので、古いバージョンでもそのまま動きます。

Implemented property hooks

プロパティフックが追加されました。

<?php
class HOGE{
	public string $tel{
		set{
			$this->tel = $value;
		}
		get => '電話番号は' . $this->tel;
	}
}

$hoge = new HOGE();
$hoge->tel = "0120444444";
echo $hoge->tel; // "電話番号は0120444444"

プロパティにsetter/getterを直接記述できる便利機能で、無駄なsetter/getterを排除できます。
文法はKotlinのそれとだいたい同じです。

Exiting a namespace now clears seen symbols

名前空間を抜けた際にシンボルもクリアされるようになりました。

ということらしいのですがよくわかりません。
テストケースを見ても何のことだかさっぱりだぜ。

Implemented asymmetric property visibility.

非対称可視性が導入されました。

class Foo{
    public private(set) string $bar = 'baz';
}

$foo = new Foo();

echo $foo->bar;    // OK
$foo->bar = 'qux'; // エラー

Foo::$barは書き込みに対してprivate、読み込みに対してpublicです。
プロパティをprivateにする最大の理由、『見られてもいいけど書き込みはされたくない』をいちいちsetterなどを使わず効率的に表現することができます。

Implemented lazy objects.

オブジェクトの遅延初期化が導入されました。

class MyClass{
    public function __construct(private int $foo){
        // 重い処理
    }
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};
$reflector = new ReflectionClass(MyClass::class);
// $objectが遅延初期化オブジェクト
$object = $reflector->newLazyGhost($initializer);

インスタンス生成は比較的重い処理なので、できればやりたくないしなるべく後回しにしたいという要件に答えます。
ただ使い方がややこしいのと、一般的にはそこまでする理由はあんまりないので、気が付いたら実はフレームワークが裏側で使っていたみたいな用途になるでしょう。

Curl

curl_version() returns an additional feature_list value

curl_versionの帰り値にfeature_listが追加されました。
SSLやIPv6など各種プロトコルに対応しているかをboolの連想配列で返します。

Added CURL_HTTP_VERSION_3 and CURL_HTTP_VERSION_3ONLY constants

CURLOPT_HTTP_VERSIONに渡せる値として定数CURL_HTTP_VERSION_3・CURL_HTTP_VERSION_3ONLYが追加されました。

Added CURLOPT_PREREQFUNCTION as a Curl option

接続の確立後、リクエストを送信するまでの間に渡せるオプションCURLOPT_PREREQFUNCTIONが追加されました。
リクエストを送信するか否かを決めるコールバックを渡せるみたい。

Added CURLOPT_SERVER_RESPONSE_TIMEOUT

定数CURLOPT_SERVER_RESPONSE_TIMEOUTが追加されました。
中身はCURLOPT_FTP_RESPONSE_TIMEOUTと同じです。

Added CURLOPT_DEBUGFUNCTION support

定数CURLOPT_DEBUGFUNCTIONが追加されました。
コールバックを渡すことでcurl標準のデバッグ関数を置き替えられるみたい。

curl_getinfo() function now returns "posttransfer_time_us"

curl_getinfoの返り値にposttransfer_time_usが追加されました。
リクエストの開始から終了までの時間を計ってくれるみたい。
リダイレクトは時間が足されていきます。

DOM

Added DOMNode::compareDocumentPosition()

メソッドDOMNode::compareDocumentPosition()が追加されました。
ふたつのノードがどちらが先にあるのかを調べます。

これ昔からシグネチャはあったものの中身が実装されてなかったからPHP8.0で削除されて、その後PHP8.4で実装されなおしたという愉快な経緯を辿ったようです。

Added constant

以下の定数が追加されました。

・DOMNode::DOCUMENT_POSITION_DISCONNECTED
・DOMNode::DOCUMENT_POSITION_PRECEDING
・DOMNode::DOCUMENT_POSITION_FOLLOWING
・DOMNode::DOCUMENT_POSITION_CONTAINS
・DOMNode::DOCUMENT_POSITION_CONTAINED_BY
・DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC

いずれもDOMの定数をそのまま取り入れただけのようです。

It is now possible to pass any callable to registerPhpFunctions()

DOMXPath::registerPhpFunctions任意のcallableを渡せるようになります。

FPM

Flushing headers without a body will now succeed

ボディが空でもflushが成功するようになりました。

とあるんだけどプルリクエストの会話を見てもいまいちわからない。
PHPからパケットを2回送ったのにnginxがコンテンツをブラウザに送信するのは一回だけだった。ならPHPからも一回にまとめて送ればいい、みたいなかんじだろうか?

Status page has a new field to display a memory peak

FPMの情報ページに表示される情報にメモリピークが追加されました。

Intl

NumberFormatter::ROUND_HALFODD added

定数NumberFormatter::ROUND_HALFODDが追加されました。
既存のNumberFormatter::ROUND_HALFEVENに対する補完です。

OpenSSL

Added support for Curve25519 + Curve448 based keys

openssl_pkey_newなどが、Curve25519Curve448に対応しました。

Implement PASSWORD_ARGON2 password hashing

password_hashがPASSWORD_ARGON2に対応しました。

OpenSSLが対応したので追随したということですが、PASSWORD_ARGON2Iとどう違うのかはよくわかりません。

PCRE

The bundled pcre2lib has been updated to version 10.44

同梱のpcre2libがバージョン10.44になりました。
結果、LoongArch JITサポート、可変長の後読みアサーションなどがサポートされました
名前付きキャプチャグループの最大長が32から128になりました。

Added support for the "r" (PCRE2_EXTRA_CASELESS_RESTRICT) modifier

修飾子rが追加されました。
iといっしょに使うと、ASCII文字と非ASCII文字の混在をlock outします。

preg_match('|aK|i', 'aK', $matches); // $matches = []

r以前にiの時点で同じだと認識しないんだけどなんでだ?

PDO

Added support for driver-specific subclasses

PDOでデータベースごとのサブクラスが実装され、データベース固有機能が使えるようになります。

// MySQL固有機能が使える
$pdo = new PdoMySql('mysql:host=localhost;dbname=test');
$pdo->getWarningCount();

// PostgreSQL固有機能が使える
$pdo = new PdoPgsql('pgsql:host=localhost;dbname=test');
$pdo->escapeIdentifier($name);

// これまでどおり
$pdo = new PDO('mysql:host=localhost;dbname=test');

固有機能を使う必要がない場合は、new PDO()のままにしておけばこれまでどおりの動きのままになります。

Added support for driver specific SQL parsers

SQLのパーサもデータベースごとに対応します。

SELECT '\'', ?'

このSQLはMySQLでは正しく動きますが、PostgreSQLでは正しく動きませんでした。
ということでMySQLにはMySQL用のパーサ、PostgreSQLにはPostgreSQL用のパーサを用意します。

Phar

Added support for the unix timestamp extension for zip archives

ZipアーカイブにUNIXタイムスタンプ拡張のサポートを追加しました。

とありますがWindowsなのでよくわかりません。

Readfile

Added ability to change .php_history path through PHP_HISTFILE env variable

対話シェルの履歴を保存しているファイルのファイルパスを変更する環境変数PHP_HISTFILEが追加されました。

Reflection

ReflectionAttribute now contains a $name property

ReflectionAttribute$nameプロパティが追加されました。

ReflectionClassConstant::__toString() and ReflectionProperty::__toString() now returns the attached doc comments

ReflectionClassConstant::__toString()ReflectionProperty::__toString()の出力に、Docコメントが追加されました。

class Hoge{
    /**
     * @var string なんか
     * @static
     */
    public const FUGA = 1;
}

$p = new ReflectionClassConstant('Hoge', 'FUGA');
echo $p;


// PHP8.3
Constant [ public int FUGA ] { 1 }

// PHP8.4
/**
  * @var     string なんか
  * @static
 */
Constant [ public int FUGA ] { 1 }

これはいったいなんの意味が…

なお、PHPDocコメントを普通に値として取ってきたい場合はgetDocComment()メソッドがあります。

Multiple methods and constants related to lazy objects were introduce

遅延初期化をリフレクションで取り扱うための各種メソッド・定数が追加されました。

・ReflectionClass::newLazyGhost()
・ReflectionClass::newLazyProxy()
・ReflectionClass::resetAsLazyGhost()
・ReflectionClass::resetAsLazyProxy()
・ReflectionClass::isUninitializedLazyObject()
・ReflectionClass::initializeLazyObject()
・ReflectionClass::markLazyObjectAsInitialized()
・ReflectionClass::getLazyInitializer()
・ReflectionProperty::skipLazyInitialization()
・ReflectionProperty::setRawValueWithoutLazyInitialization()
・ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
・ReflectionClass::SKIP_DESTRUCTOR

SOAP

Added support for clark notation for namespaces in class map

クラスマップをClark記法に対応しました。

ということらしいのですが公的情報が全く見当たりません。
どうもXMLの仕様を作ったJames Clark非公式に使っていた短縮記法みたい。

Instances of DateTimeInterface that are passed to xsd:datetime or similar elements are now serialized as such

DateTimeInterfaceをxsd:datetimeに渡した場合、これまでは空文字にされていたのが適切な文字列にシリアライズされるようになりました。

Session persistence now works with a shared session module

持続的セッションが共有セッションモジュールで動作するようになりましたとあるのですが、正直何言ってるのかわからない。
まず共有セッションモジュールってなんやねん。
まあともかく、一部の特殊なサーバでもSoapServer::setPersistenceが効くようになったってことでいいんですかね。

Standard

Added a new RoundingMode enum with clearer naming and improved discoverability

新しいENUM、RoundingModeが追加されました。

PHP8.4でround関数の丸めモードが増えて8つになったのですが、定数を増やすのはつらいということでRoundingModeにまとめることになりました。
既存の定数が削除される予定はいまのところありません。

round(1.5, 1, PHP_ROUND_HALF_UP);
round(1.5, 1, \RoundingMode::HalfAwayFromZero); // PHP_ROUND_HALF_UPと同じ

round(1.5, 1, \RoundingMode::PositiveInfinity); // 切り上げ
round(1.5, 1, \RoundingMode::NegativeInfinity); // 切り捨て

XSL

It is now possible to use parameters that contain both single and double quotes

シングルクォートとダブルクォートを両方含んだ文字列を扱えるようになりました。

実はこれまでできませんでした

It is now possible to pass any callable to registerPhpFunctions()

DOMXPath::registerPhpFunctions()の引数にcallableを渡せるようになりました

$xpath->registerPhpFunctions("callable"); // PHP8.3
$xpath->registerPhpFunctions(["function_name" => $callable]); // PHP8.4

これまでは関数名の文字列しか渡すことができませんでした。

Added XSLTProcessor::$maxTemplateDepth and XSLTProcessor::$maxTemplateVars

XSLTProcessorにプロパティ$maxTemplateDepth$maxTemplateVarsが追加されました。
詳細はよくわかりませんがまあ名前のとおりドキュメントの広さを制限することができるパラメータでしょう。

Zip

Added ZipArchive::ER_TRUNCATED_ZIP added in libzip 1.11

定数ZipArchive::ER_TRUNCATED_ZIPが追加されました。
これはlibzip 1.11で追加されたエラーコードです。

Changes in SAPI modules

SAPIの変更。

apache2handler

Support for EOL Apache 2.0 and 2.2 has been removed

EOLになっているApache 2.0と2.2のサポートが削除されました。
PHP8.4が対応しているApacheの最低バージョンは2.4です。

CLI

The behavior has been changed to look for an index file in all cases

ビルトインサーバは、指定されたファイルが見つからないときに親ディレクトリに遡って探しています。
しかし、ファイル名に.が含まれていた場合は遡らないようになっていました。
PHP8.4では、ファイル名に.が含まれていた場合でもディレクトリを遡ってファイルを探すようになりました。

FPM

/dev/poll events.mechanism setting for Solaris/Illumos had been retired

Solaris用に存在していたevents.mechanismというイベントメカニズムは削除されました。

Solarisなんて使ったことないからなんのことかわかりません。

Deprecated Functionality

非推奨になる機能。
基本的にPHP8.4でE_DEPRECATEDとなり、PHP9.0で削除されます。
この機能・書き方は今後使ってはいけません。

Core

Implicitly nullable parameter types are now deprecated

引数のデフォルトNULLが禁止されます。

function foo(int $x = null) {
    // Deprecated
}

引数の型はintなのに引数を渡さないことが可能なので、型is何?ってなります。

これはNullableが導入されたのがPHP7.1だったので、それ以前と互換性を保つためにあえて許されていた構文です。
しかしいいかげんもういいだろうということで禁止となり、今後は正しくfunction foo(?int $x)とする必要があります。

Passing E_USER_ERROR to trigger_error() is now deprecated

trigger_error()E_USER_ERRORを出すことを禁止します。
これはPHP本体が出すE_ERRORと同ランクの致命的なエラーであり、デストラクタやfinallyもパスして実行が即座に中断されます。
適切な回復メカニズムを実行できないのはよろしくないということで、今後は普通にExceptionを使ってくれということになりました。

Using "_" as a class name is now deprecated

クラス名_が禁止されます。

class _ {} // Deprecated

むしろ今まで作れてたんかよ。

今後パターンマッチングの導入が予定されており、そのために必要となるので布石を打っておくという面もあるようです。

Raising zero to the power of negative number is deprecated

ゼロのマイナス累乗が禁止されます。

var_dump(0 ** -1);

// PHP8.3 float(INF)
// PHP8.4 float(INF) Deprecated
// PHP9.0 DivisionByZeroError

そもそも数学的にはどうなるのが正しいのだろう。

The E_STRICT constant was deprecated

E_STRICTがなくなりました。

これは元々PHP5時代に不適切なコーディングを防ぐために導入されたものですが、PHP7から8にかけてE_WARNINGなどに振り分けられました。
PHP本体のE_STRICTは2019年に消滅したため、E_STRICT定数も機能も削除します。

Curl

The CURLOPT_BINARYTRANSFER constant is deprecated

定数CURLOPT_BINARYTRANSFERが削除されました。

これ、なんとPHP5.1.3で不要となったものであり、定数だけが今まで残っていました。

Date

Calling DatePeriod::__construct(string $isostr, int $options = 0) is deprecated

DatePeriod::__construct()にstringを渡す方法が削除されました。
かわりにDateTimeInterfaceを渡すか、DatePeriod::createFromISO8601String()を使いましょう。

Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and SUNFUNCS_RET_DOUBLE are now deprecated

定数SUNFUNCS_RET_TIMESTAMPSUNFUNCS_RET_STRINGSUNFUNCS_RET_DOUBLEが削除されました。

そもそもこの定数を使っている関数date_sunrise()非推奨になったためです。

DBA

Passing null or false to dba_key_split() is deprecated

dba_key_splitの引数null・falseが削除されました。
実体のある文字列を渡す必要があります。

DOM

Deprecated DOM_PHP_ERR constant

定数DOM_PHP_ERRが削除されました

DOMの仕様にない非標準のエラーコードです。

DOMEntity::$encoding, DOMEntity::$version have been deprecated

DOMEntity::$encodingなど幾つかのプロパティが削除されました

これらは少なくとも17年にわたって非推奨でした。

Hash

Deprecated passing incorrect data types for options to ext/hash functions

一部のハッシュ関数は、追加のオプションを配列で渡すことができます。
たとえばハッシュアルゴリズムmurmurseedxxh3secretを受け取ります。

しかし、seedにint型以外を渡したり、secretにstring型以外を渡したりすると、何ひとつエラーを吐かずに無視します。

わかりにくいので、正しくない型を渡した場合にValueErrorを出すようにします。

Intl

Calling intlcal_set() as well as calling IntlCalendar::set() with more than 2 arguments is deprecated

IntlCalendar::set()に大量の引数を渡す方のシグネチャが削除されました。
一括設定したい場合はIntlCalendar::setDateTime()を使いましょう。

Calling intlgregcal_create_instance() as well as calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated

IntlGregorianCalendar::__construct()に大量の引数を渡す方のシグネチャが削除されました。
一括設定したい場合はIntlCalendar::createFromDateTime()を使いましょう。

LDAP

Calling ldap_connect() with more than 2 arguments is deprecated

ldap_connectに大量の引数を渡す方のシグネチャが削除されました。
一括設定したい場合はldap_connect_walletを使いましょう。

Calling ldap_exop() with more than 4 arguments is deprecated

ldap_exopに大量の引数を渡す方のシグネチャが削除されました。
一括設定したい場合はldap_exop_syncを使いましょう。

Mysqli

The mysqli_ping() function and mysqli::ping() method are now deprecated

mysqli_ping削除されました

これは設定mysqli.reconnectが有効であれば自動再接続しに行くという機能なのですが、mysqli.reconnect自体がPHP8.2で削除されています。

The mysqli_kill() function and mysqli::kill() method are now deprecated

mysqli_kill削除されました

これはMySQLのCOM_PROCESS_KILLのラッパーなのですが、COM_PROCESS_KILLがMySQL5.7で非推奨になったためです。

The mysqli_refresh() function and mysqli::refresh() method are now deprecated

mysqli_refresh削除されました

こちらもMySQL側でCOM_REFRESHが非推奨になったためです。

Passing explicitly the $mode parameter to mysqli_store_result() has been deprecated

mysqli_store_resultの第二引数$result削除されました

この引数はPHP8.1で無効化されました
今までは指定しても何も起きませんが、PHP8.4ではE_DEPRECATDを出します。

PDO_PGSQL

Using escaped question marks (??) inside dollar-quoted strings is deprecated

ドルマークで囲まれた文字列内では?のエスケープ??が不要になりました。

Postgresは全然使わないのでよくわからないのですが、特定の書式において?プレースホルダを使う場合、これまでは??にしないといけなかったのがしなくてよくなったということのようです。
ドライバごとに個々のSQLのパーサを用意した結果です。

PgSQL

Calling pg_fetch_result() with 2 arguments is deprecated

pg_fetch_resultに2引数を渡す方のシグネチャが削除されました。
3引数のほうを使うようにしましょう。

Calling pg_field_prtlen() with 2 arguments is deprecated

pg_field_prtlenに2引数を渡す方のシグネチャが削除されました。
3引数のほうを使うようにしましょう。

Calling pg_field_is_null() with 2 arguments is deprecated

pg_field_is_nullに2引数を渡す方のシグネチャが削除されました。
3引数のほうを使うようにしましょう。

Random

lcg_value() is deprecated, as the function is broken in multiple ways.

lcg_valueが削除されました。
この関数は暗号学的にセキュアではなく、返り値に偏りがあるなど、質のよくない乱数生成器です。

Random\Randomizer::getFloatが上位互換なのでこちらを使いましょう。

Reflection

Calling ReflectionMethod::__construct() with 1 argument is deprecated

pg_field_is_nullに1引数を渡す方のシグネチャが削除されました。
2引数のほう、もしくはReflectionMethod::createFromMethodNameを使うようにしましょう。

Session

Calling session_set_save_handler() with more than 2 arguments is deprecated

session_set_save_handlerたくさんの引数を渡す方のシグネチャが削除されました。
2引数のほうを使うようにしましょう。

Changing the INI settings session.sid_length and session.sid_bits_per_character is deprecated

INI設定session.sid_lengthとsession.sid_bits_per_character削除されました

これはセッションIDの長さや文字種を変更できるというパラメータですが、設定によってはWAFがエラーを出すことがわかりました。
そもそもセッションIDの暗号強度をユーザが調整する必要性そのものが皆無であり、常に安全性高めのセッションIDにしておけばいいだろうということで、設定値を変更することが不可能になります。

Changing the INI settings session.use_only_cookies, session.use_trans_sid, session.trans_sid_tags, session.trans_sid_hosts, and session.referer_check is deprecated

INI設定session.use_only_cookiesなどいくつかの設定が削除されました

これはセッションIDをURLに埋め込んでいた超古代文明の遺物であり、現代には全く不要であるため削除されます。

SOAP

The SOAP_FUNCTIONS_ALL constant is now deprecated

定数SOAP_FUNCTIONS_ALL削除されました

これはSOAPサーバで全てのPHP関数を使用可能にするという設定であり、潜在的な脆弱性が存在するため削除されます。

Passing an int to SoapServer::addFunction() is now deprecated

SoapServer::addFunctionの引数にintを渡すシグネチャは削除されました

intを受け入れる唯一の引数がSOAP_FUNCTIONS_ALLだったため、SOAP_FUNCTIONS_ALLといっしょに削除されます。

SPL

The SplFixedArray::__wakeup() method has been deprecated

SplFixedArray::__wakeup()は削除されました。

かわりに__serialize()__unserialize()を使いましょう。

Using the default value for $escape parameter is now deprecated

SplFileObject::setCsvControl()SplFileObject::fputcsv()SplFileObject::fgetcsv()の引数$escape必須になりました

fputcsvなど昔からPHPにあるCSV関数は引数$escapeを持っているのですが、これを下手に変更するとバグることが知られています。
元々CSVフォーマットにエスケープの標準化がなかったせいで起きている混乱なのですが、現在ではほぼ"が使われているので、最終的にそれに合わせる目的のようです。
でもそのために必須にするという解決策は正直よくわからない。

fgetcsv($fp, length:null); // E_DEPRECATED the $escape parameter must be provided as its default value will change
fgetcsv($fp, length:null, escape:''); // OK
fgetcsv($fp, length:null, escape:'"'); // OK
fgetcsv($fp, length:null, escape:'@@'); // ValueError Argument #5 ($escape) must be empty or a single character

Standard

Using the default value for $escape parameter is now deprecated

fputcsvfgetcsvstr_getcsvの引数$escape必須になりました

上のSplFileObject::setCsvControl()と全く同じ理由です。

Calling stream_context_set_option() with 2 arguments is deprecated

stream_context_set_optionに2引数を渡す方のシグネチャが削除されました。
4引数のほうを使うか、stream_context_set_optionsを使いましょう。

Unserializing strings using the uppercase 'S' tag is deprecated

unserializeのパーサメカニズムのうち、Sタグの対応が削除されました

これはそもそもリリースされていないバージョンのPHP6でしか生成されないタグであり、シリアライズされた文字列を直接編集しないかぎり絶対に出てこないので、一般ユーザには全く影響しないでしょう。

unserialize('S:1:"a";'); // Unserializing the 'S' format is deprecated

XML

The xml_set_object() function has been deprecated

xml_set_object()削除されました

かわりにxml_set_XXX_handlerを使いましょう。

Passing non-callable strings to the xml_set_*_handler() functions is now deprecated

xml_set_XXX_handlerの引数$handlerにcallable以外を渡すことが禁止されました。

これまでは文字列を渡すと、xml_set_object()で渡したオブジェクトの中の該当メソッドが実行されていました。
これは良く使われているオブジェクト呼び出し構文[インスタンス名, メソッド名]とかけ離れていてわかりにくいため、機能を削除します。

Changed Functions

変更のあった関数。

Core

trigger_error() and user_error() now have a return type of true instead of bool

trigger_erroruser_errorの返り値の型がboolからtrueになりました。

元々trueしか返さなかったので実情に合わせただけです。

DOM

DOMDocument::registerNodeClass() now has a tentative return type of true

DOMDocument::registerNodeClass()の返り値の型がboolからtrueになりました。

Hash

Changed the return type of hash_update() to true

hash_update()の返り値の型がboolからtrueになりました。

Intl

NumberFormatter::ROUND_TOWARD_ZERO and NumberFormatter::ROUND_AWAY_FROM_ZERO have been added

NumberFormatterにクラス定数ROUND_TOWARD_ZEROとROUND_AWAY_FROM_ZEROが追加されました。
値はROUND_DOWN・ROUND_UPと同じです。
これはround()に追加された定数RoundingMode::TowardsZero等と形を合わせたものとなります。

ResourceBundle::get() now has a tentative return type of: ResourceBundle|array|string|int|null

ResourceBundle::getの返り値の型がResourceBundle|array|string|int|nullになりました。

ちょっとどうなんだという型ですが、これは暫定的な値のようです。

The idn_to_ascii() and idn_to_utf8() now always throw ValueErrors if the $domain name is empty or too long, and if $variant is not INTL_IDNA_VARIANT_UTS46

idn_to_asciiidn_to_utf8は、cvariantがINTL_IDNA_VARIANT_UTS46でなければValueErrorを出すようになりました。

LibXML

libxml_set_streams_context() now immediately throws a TypeError when a non-stream-context resource is passed to the function

libxml_set_streams_context()のエラーが発生するタイミングが早まりました。
これまでは引数が正しくなかった場合、生成されたストリームを実際に使おうとした段階でようやくエラーが発生していたのですが、今後はlibxml_set_streams_context()を呼んだ時点ですぐ発生します。

MBString

The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16 strings

mb_strcut()に、正しくないフォーマットのUTF-8文字列を渡したときの挙動が一貫性を持つようになりました。
正しいフォーマットのUTF-8については動作に変更ありません。

正しくないんだからどうでもいい気はしますけどね。

ODBC

Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and odbc_fetch_into() now has a default value of null

odbc_fetch_object()odbc_fetch_array()odbc_fetch_into()の引数$rowのデフォルト値がnullになりました。

odbc_fetch_row()はnullだったので、これと合わせました。
これまではそれぞれ-1,-1,0とバラバラでした。

OpenSSL

The extra_attributes parameter in openssl_csr_new sets CSR attributes

openssl_csr_newの引数$extra_attributesはCSR属性を設定するようになりました。

これまでは誤ってDN Subjectを設定していたそうです。ええ……

まあPHPでSSL証明書をどうこうするなんて普通はやらないですよね。

The dn parameter in openssl_csr_new allows setting array of values for a single entry

openssl_csr_new()の引数$distinguished_namesは、ひとつの項目に値を配列で設定できるようになりました。

New serial_hex parameter added to openssl_csr_sign to allow setting serial number in the hexadecimal format

openssl_csr_sign()に引数$serial_hexが追加されました。

シリアル番号を16進形式で設定できます。
引数$serialとの違いはよくわからない。

Parsing ASN.1 UTCTime by openssl_x509_parse fails if seconds are omitted for OpenSSL version below 3.2 (-1 is returned for such fields)

OpenSSL3.2未満で、秒数が入っていないASN.1 UTCTimeについては、openssl_x509_parse()で該当フィールドのパースが失敗します。
OpenSSL3.3以上では証明書の読み込み自体ができません。

Output

Output handler status flags passed to the flags parameter of ob_start are now cleared

ob_start()の出力ハンドラについて、引数$flagsで渡したステータスフラグがクリアされるようになりました。

とあるんだけど意味がよくわからない

PDO

getAttribute, enabled to get the value of ATTR_STRINGIFY_FETCHES

PDO::getAttribute()ATTR_STRINGIFY_FETCHESが取得できるようになりました。

PDO_FIREBIRD

getAttribute, enabled to get values of FB_ATTR_DATE_FORMAT, FB_ATTR_TIME_FORMAT, FB_ATTR_TIMESTAMP_FORMAT.

PDO::getAttribute()FB_ATTR_DATE_FORMAT・FB_ATTR_TIME_FORMAT・FB_ATTR_TIMESTAMP_FORMATが取得できるようになりました。

Added new attributes to specify transaction isolation level and access mode

トランザクション分離レベルとアクセスレベルを設定するための新しい属性と定数が追加されました。

$dbh->setAttribute(PDO\Firebird::TRANSACTION_ISOLATION_LEVEL, PDO\Firebird::REPEATABLE_READ);
$dbh->setAttribute(PDO\Firebird::WRITABLE_TRANSACTION, false);

トランザクション分離レベルはPdo\Firebird::READ_COMMITTEDPdo\Firebird::REPEATABLE_READPdo\Firebird::SERIALIZABLEの3種類、アクセスレベルはtrue=読み書き、false=読み込みオンリーの2種類です。

When using persistent connections, there is now a liveness check in the constructor

永続的接続を使う際、コンストラクタでliveness checkが行われるようになりました。

liveness checkってなんだ?

added static method Pdo\Firebird::getApiVersion() to obtain that value

FB_API_VERを取得するstaticメソッドPdo\Firebird::getApiVersion()が追加されました。
FB_API_VERはphpinfoにも出力されます。

Five new data types are now available: INT128, DEC16, DEC34, TIMESTAMP_TZ, TIME_TZ

Firebird4.0以降で、5種類のデータ型が追加されました。
INT128DEC16DEC34TIMESTAMP_TZTIME_TZ

PDO_MYSQL

getAttribute, enabled to get the value of ATTR_FETCH_TABLE_NAMES

PDO::getAttribute()ATTR_FETCH_TABLE_NAMESが取得できるようになりました。

PDO_PGSQL

getAttribute() can now retrieve the memory usage of query results

PDO::getAttribute()PDO::PGSQL_ATTR_RESULT_MEMORY_SIZEが取得できるようになりました。
クエリのメモリ使用量を確認できます。

If the column is of FLOAT4OID/FLOAT8OID type, query returns it as a float instead of a string

FLOAT4OID・FLOAT8OID型のカラムの型がstringからfloatになりました。

PgSQL

pg_select, the conditions arguments accepts an empty array and is optional.

pg_select()の引数$conditionsがオプショナル化され、空配列も受け入れるようになりました。

Phar

Phar::setAlias() and Phar::setDefaultStub() methods now have a tentative return type of true instead of bool

Phar::setAlias()Phar::setDefaultStub()の返り値の型がboolからtrueになりました。

POSIX

posix_isatty now sets the error number when the file descriptor/stream argument is invalid

posix_isatty()は引数$file_descriptorが無効な場合にエラー番号を設定するようになりました。

設定って何処に設定するんだ?返り値?

Reflection

ReflectionGenerator::getFunction() may now be called after the generator finished executing

既に使い果たしたジェネレータからもReflectionGenerator::getFunctionを呼ぶことができるようになりました。

function gen(){
    yield 1;
}
$gen = gen();
foreach($gen as $v){
    var_dump($v);
}
$reflectionGen = new ReflectionGenerator($gen);
var_dump($reflectionGen->getFunction());

// PHP8.4 object(ReflectionFunction)
// PHP8.3 Uncaught ReflectionException: Cannot create ReflectionGenerator based on a terminated Generator

Sockets

Parameter $backlog of socket_create_listen() now has a default value of SOMAXCONN

socket_create_listenの引数$backlogのデフォルト値が定数SOMAXCONNになりました。

これまでは128固定でした。

SPL

SplPriorityQueue::insert() and SplPriorityQueue::recoverFromCorruption() now has a tentative return type of true

SplPriorityQueue::insert()SplPriorityQueue::recoverFromCorruption()の返り値の型がboolからtrueになりました。

SplHeap::insert() and SplHeap::recoverFromCorruption() now has a tentative return type of true instead of bool

SplHeap::insert()SplHeap::recoverFromCorruption()の返り値の型がboolからtrueになりました。

Standard

The internal implementation for rounding to integers has been rewritten

丸め関数の内部実装をリファクタリングし、いくつかのバグが修正されました。
より正しい方向に値が変わることがあります。

var_dump(round(0.49999999999999994));

// PHP8.4 0
// PHP8.3 1

The $mode parameter of the round() function has been widened to RoundingMode|int, accepting instances of a new RoundingMode enum

round()の引数$modeの型がintからRoundingMode|intなりました

Four new modes have been added to the round() function

round()の丸めモードが4種類追加されました

・RoundingMode::PositiveInfinity 引数より大きい最小の整数に丸める。
・RoundingMode::NegativeInfinity 引数より小さい最大の整数に丸める。
・RoundingMode::AwayFromZero ゼロから離れた方に丸める。
・RoundingMode::TowardsZero ゼロに近い方に丸める。

Fixed a bug caused by "pre-rounding" of the round() function

round関数のpre-roundingに起因するバグが修正されました。

たとえば0.285は内部的には0.28499999999999998なんだけど計算しやすいように事前に0.29にしてから計算していた、みたいなことをやっていたらしいんだけど、これをなくしたようです。
結果として、round()はたまに正しくない値を返してくるエッジケースがあるのですが、その頻度が減ります。

The maximum precision that can be handled by round() has been extended by one digit

round関数の有効桁数が1桁増えました。

var_dump(round(4503599627370495.5));

// PHP8.4 4503599627370496
// PHP8.3 4503599627370495.5

The default value of the 'cost' option for PASSWORD_BCRYPT for password_hash() has been increased from '10' to '12'.

password_hash()のアルゴリズムPASSWORD_BCRYPTについて、コストのデフォルト値が10から12になりました

debug_zval_dump() now indicates whether an array is packed.

debug_zval_dump()は配列がpackedされているかを出力するようになりました。

debug_zval_dump([2=>1, 4=>1]); // packed refcount{}
debug_zval_dump([4=>1, 2=>1]); // refcount{}

このスライドだと0スタート昇順の場合のみpackedと書いてあるんだけど、試してみたら0スタートでなくても抜けがあってもpakedになるみたいでした。
逆順ではさすがにpackedになりませんでした。

long2ip() now returns string instead of string|false

long2ip()の返り値の型がstring|falseからstringになりました。

output_add_rewrite_var() now uses url_rewriter.hosts instead of session.trans_sid_hosts for selecting hosts that will be rewritten

output_add_rewrite_var()は、書き替えるホストの判断にsession.trans_sid_hostsではなくurl_rewriter.hostsを使うようになりました。

highlight_string() now has a return type of string|true instead of string|bool.

highlight_string()の返り値の型がstring|boolからstring|trueになりました。

print_r() now has a return type of string|true instead of string|bool.

print_r()の返り値の型がstring|boolからstring|trueになりました。

New Functions

新しく追加された関数。

Core

request_parse_body()

関数request_parse_body()が追加されました。

POST以外のリクエストメソッドでもリクエストボディを取得できます。

BCMath

Added bcfloor(), bcceil(), bcround()

BCMathに丸め関数bcfloor()・bcceil()・bcround()が追加されました。

Added bcdivmod()

BCMathに商と余りを取得する関数bcdivmod()が追加されました。

Date

Added static methods DateTime[Immutable]::createFromTimestamp(int|float $timestamp): static.

タイムスタンプからDateTimeを生成する関数です。

Added method DateTime[Immutable]::getMicrosecond(): int

マイクロ秒を取得する関数です。

Added method DateTime[Immutable]::setMicrosecond(int $microsecond): static.

マイクロ秒を設定する関数です。

DOM

Added DOMNode::compareDocumentPosition().

ふたつのDOMノードのどちらが先にあるか調べます

Added DOMXPath::registerPhpFunctionNS()

XPath式内でPHP関数を使えるようになります。

既にほぼ同じ関数DOMXPath::registerPhpFunctionsがありますが、こちらは文字列のみ、registerPhpFunctionNSはコールバックを渡せるという違いがあるようです。
DOMは全然使わないので正直よくわかりません。

Added DOMXPath::quote() to quote a string for use in an XPath expression

XPath用のエスケープ関数DOMXPath::quoteが追加されました。

$query = "//book[@name=" . DOMXPath::quote($text) . "]";

Hash

Added HashContext::__debugInfo().

メソッドHashContext::__debugInfo()が追加されました。

__debugInfovar_dumpの出力を変更できるマジックメソッドです。
従ってHashContextの出力が変更されるはずですが、このメソッドなぜか情報が一切出てこないので詳細不明。

Intl

Added IntlTimeZone::getIanaID()/intltz_get_iana_id() to the IANA identifier from a given timezone

タイムゾーン識別子を正規化して返すメソッドIntlTimeZone::getIanaID()が追加されました。

var_dump(IntlTimeZone::getIanaID('Japan')); // Asia/Tokyo

単にICUの同名関数のラッパーであり、変換リストを通しているだけのようです。

Added grapheme_str_split which allow to support emoji and Variation Selectors

関数grapheme_str_splitが追加されました。

絵文字を正しく分割できる関数です。

var_dump(grapheme_str_split('👨‍👩‍👦‍👦')); // [👨‍👩‍👦‍👦]

Added IntlDateFormatter::parseToCalendar which behaves like IntlDateFormatter::parse except the time zone is updated

メソッドIntlDateFormatter::parseToCalendar()が追加されました。

IntlDateFormatter::parseと同じだけどタイムゾーンを考慮する?
よくわからない。
そもそもIntlの日時オブジェクト自体が地獄みたいな仕様だから(PHPのせいではなくIntlのせい)使うことないからいいや。

Added SpoofChecker::setAllowedChars to limit the range of unicode chars

メソッドSpoofChecker::setAllowedChars()が追加されました。

UNICODE文字範囲を制限するということらしいですがこれまたよくわかりません。
これもICUライブラリからそのままもってきた関数だと思われます。

MBString

Added mb_trim, mb_ltrim and mb_rtrim functions

関数mb_trim()mb_ltrim()mb_rtrim()が追加されました。

マルチバイトtrim関数です。

Added mb_ucfirst and mb_lcfirst functions

関数mb_ucfirst()mb_lcfirst()が追加されました。

マルチバイトucfirst関数です。

OPCache

Added opcache_jit_blacklist function. It allows skipping the tracing JIT execution of select functions

関数opcache_jit_blacklist()が追加されました。

この関数で指定した関数は、JITの適用外になるみたいです。

PCNTL

pcntlぜんぜんわからん。

Added pcntl_setns allowing a process to be reassociated with a namespace in order to share resources with other processes within this context

関数pcntl_setns()が追加されました。

プロセスを既存の名前空間に関連付けられるようにします。
pcntl_unshareの逆みたいです。

Added pcntl_getcpuaffinity to get the cpu(s) bound to a process and pcntl_setcpuaffinity to bind 1 or more cpus to a process.

関数pcntl_getcpuaffinity()pcntl_setcpuaffinity()が追加されました。

pcntl_setcpuaffinityでプロセスにCPUをバインドし、pcntl_getcpuaffinityはプロセスにバインドされているCPUを取得します。

Added pcntl_getcpu to get the cpu id from where the current process runs.

関数pcntl_getcpu()が追加されました。

現在プロセスが実行されているCPU IDを取得します。

Added pcntl_getqos_class to get the QoS level (aka performance and related energy consumption) of the current process and pcntl_setqos_class to set it

関数pcntl_getqos_class()pcntl_setqos_class()が追加されました。

pcntl_setqos_classで現在のプロセスのQoSレベルを設定し、pcntl_getqos_classは現在の設定値を取得します。

QoSといってもタスクの優先順位についての話のようです

Added pcntl_waitid to obtain status information pertaining to termination, stop, and/or continue events in one of the caller's child processes

関数pcntl_waitid()が追加されました。

子プロセスの状態が変化するまで待機する関数のようです。

PDO_PGSQL

Added Pdo\Pgsql::setNoticeCallback() to allow a callback to be triggered on every notice sent

メソッドPdo\Pgsql::setNoticeCallback()が追加されました。

NOTICEが発行された際に呼び出されるコールバックを登録できます。

PgSQL

MySQLしか使ってないからPostgresの理解はふわふわです。

Added pg_change_password to alter a given user's password.

関数pg_change_password()が追加されました。

指定ユーザのパスワードを変更します。

Added pg_put_copy_data to send COPY commands and pg_put_copy_end to send end-of-data to the server

関数pg_put_copy_data()pg_put_copy_end()が追加されました。

COPYコマンドの開始と終了を送信する用です。

Added pg_socket_poll to check if there is any read and/or write events with an optional timeout

関数pg_socket_poll()が追加されました。

読み取りイベント・書き込みイベントが残っているかを調べるようです。

Added pg_jit to get informations on the server JIT support.

関数pg_jit()が追加されました。

サーバがJITをサポートしているかの情報を取得します。

Added pg_set_chunked_rows_size to allow to fetch results in chunk of max N rows

関数pg_set_chunked_rows_size()が追加されました。

チャンクモードで結果を取得する行数を設定します。
大きな結果を取得したいときに少しずつ取りに行くあれです。

Added pg_result_memory_size to get the visibility the memory used by a query result.

関数pg_result_memory_size()が追加されました。

SQLクエリのメモリ使用量を調べることができます。

Reflection

Multiple methods related to lazy objects were introduced

遅延初期化に関するメソッドが追加されました。

・ReflectionClass::newLazyGhost()
・ReflectionClass::newLazyProxy()
・ReflectionClass::resetAsLazyGhost()
・ReflectionClass::resetAsLazyProxy()
・ReflectionClass::isUninitializedLazyObject()
・ReflectionClass::initializeLazyObject()
・ReflectionClass::markLazyObjectAsInitialized()
・ReflectionClass::getLazyInitializer()
・ReflectionProperty::skipLazyInitialization()
・ReflectionProperty::setRawValueWithoutLazyInitialization()

ReflectionClassConstant::isDeprecated() was introduced.

メソッドReflectionClassConstant::isDeprecated()が追加されました。

@Deprecatedを検出します。

ReflectionGenerator::isClosed() was introduced.

メソッドReflectionGenerator::isClosed()が追加されました。

そのジェネレータが既に終了しているかを調べます。

ReflectionProperty::isDynamic() was introduced.

メソッドReflectionProperty::isDynamic()が追加されました。

そのプロパティが動的プロパティかを調べます

$hoge = new class{
    public $s = 1;
};
$hoge->d = 1;

$reflector = new ReflectionObject($hoge);
var_dump($reflector->getProperty('s')->isDynamic()); // false
var_dump($reflector->getProperty('d')->isDynamic()); // true

動的プロパティはPHP9.0で使えなくなることが決定しています。
従ってLinterや移行支援ツールにとって有用となるでしょう。

Sodium

Added the sodium_crypto_aead_aegis128l_() and sodium_crypto_aead_aegis256l_() functions

関数sodium_crypto_aead_aegis128l_*()sodium_crypto_aead_aegis256l_*()が追加されました。

libsodium 1.0.19AEGISがサポートされたので、その対応のためです。

しかしアルゴリズムごとに個別に関数を作っているせいで関数一覧がえらいことになっているので早くオブジェクトにしてくれって思いますよね。

sodium_crypto_aead_aes256gcm_*() functions are now enabled on aarch64 CPUs with the ARM cryptographic extensions.

関数sodium_crypto_aead_aes256gcm_*()がaarch64 CPUでも動くようになりました。
これ新関数の段に書いてあるのですが、PHP7.2からあったので新関数じゃないですよね。

SPL

Added seek() method to SplObjectStorage, now it implements SeekableIterator

メソッドSplObjectStorage::seek()が追加されました。

SOAP

Added SoapServer::__getLastResponse()

メソッドSoapServer::__getLastResponse()が追加されました。

SoapServer::__construct()の引数$optionsでtrace=trueになっていた場合に、最終応答を返します。

Standard

Added the http_get_last_response_headers() and http_clear_last_response_headers() that allows retrieving the same content as the magic $http_response_header variable.

関数http_get_last_response_headers()http_clear_last_response_headers()が追加されました。

file_get_contents()した直後に呼ぶと、そのリクエストで発生したヘッダを取得することができます。
謎変数$http_response_header削除するための布石です。

Added function fpow() following rules of IEEE 754.

関数fpow()が追加されました。

IEEE754に従うpow()です。

Added functions array_find(), array_find_key(), array_all(), and array_any()

関数array_find()array_find_key()array_all()and array_any()が追加されました。

配列をコールバックで任意検索できる便利な関数群です。

$array = [
    'a' => 'dog',
    'b' => 'cat',
    'c' => 'cow',
    'd' => 'duck',
    'e' => 'goose',
    'f' => 'elephant'
];
 
// 5文字以上の値を検索
var_dump(array_find($array, function (string $value) {
    return strlen($value) > 4;
})); // string(5) "goose"

// 1文字目がキーになっている値を検索してキーを返す
var_dump(array_find_key($array, function (string $value, $key) {
   return $value[0] === $key;
})); // string(1) "c"

// 5文字以上の値が存在するか
var_dump(array_any($array, function (string $value) {
    return strlen($value) > 5;
})); // bool(true)

// 全ての値が6文字以上か
var_dump(array_all($array, function (string $value) {
    return strlen($value) > 5;
})); // bool(false)

Tidy

Added tidyNode::getNextSibling() and tidyNode::getPreviousSibling().

メソッドtidyNode::getNextSibling()tidyNode::getPreviousSibling()が追加されました。

それぞれ次の兄弟ノード手前の兄弟ノードを返します。

XMLReader

Added XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString()

メソッドXMLReader::fromStream()XMLReader::fromUri()XMLReader::fromString()が追加されました。

元々のRFCはストリームからXMLを作る方法がないのでfromStreamを追加したいというものでした。
名前を揃えてXMLReader::openのエイリアスfromUri、XMLReader::XMLのエイリアスfromStringも追加されました。
実際はエイリアスではなく微妙に違うみたいですが。

XMLWriter

メソッドXMLWriter::toStream()XMLWriter::toUri()XMLWriter::toMemory()が追加されました。

動機はXMLReaderと同じです。

XSL

Added XSLTProcessor::registerPhpFunctionNS()

メソッドXSLTProcessor::registerPhpFunctionNS()が追加されました。

DOMXPath::registerPhpFunctionNS()と同じです。

New Classes and Interfaces

新しいクラス・インターフェイス。

BCMath

Added BcMath\Number class

クラスBcMath\Number追加されました

これはイミュータブルであり、BCMath関数の全てをメソッドとして持っています。

$a = new BcMath\Number(100);
$b = $a->add(50);
$c = $b->divmod(40);
var_dump($c); [BcMath\Number(3), BcMath\Number(30)]

手続き型インターフェイスしか存在しない特殊なGMPクラスと異なり、こちらは思った通りの操作が行えるオブジェクトです。

Core

RequestParseBodyException

request_parse_body()で発生することがある例外です。

#[\Deprecated] attribute.

アトリビュートDeprecatedです。

DBA

Dba\Connection opaque object replacing DBA resources

DBAがリソースからDba\Connectionオブジェクトになりました。

DOM

Implemented DOM HTML5 parsing and serialization.

DOM関連クラスが複数追加されました

これまでPHPが使っていたDOMライブラリはHTML5に対応しておらず、HTML5の読み書きが困難でした。
そのため新たなライブラリを導入し、PHPからはDom\HTMLDocumentDom\XMLDocumentで使えるようにします。

Implemented opt-in ext/dom spec compliance RFC.

DOM関連クラスが複数追加されました

古いDOMを、HTML5対応の新しいDOMドキュメントに変換するためのものです。

Implemented "New ext-dom features in PHP 8.4" RFC.

DOM関連クラスがさらに追加されました

querySelectorなどのこれまでなかった便利機能が追加されます。

ODBC

Odbc\Connection

Odbc\Result

ODBCがリソースからオブジェクトになりました。

PDO

Pdo\DbLib

Pdo\Firebird

Pdo\Mysql

Pdo\Odbc

Pdo\Pgsql

Pdo\Sqlite

PDOがドライバごとの専用オブジェクトを使えるようになりました。

Reflection

ReflectionConstant

定数に関するリフレクションを表すクラスです。

SOAP

Soap\Url

Soap\Sdl

Standard

StreamBucket

stream_bucket_newの返り値として使われます。
これまではstdClassでした。

Removed Extensions and SAPIs

削除されたエクステンションなど。

IMAP

IMAPは同梱されなくなりました。
当面はPECLからインストールできます。

IMAPが使っているライブラリuw-imap/imapは更新が滞っており、OAuthに対応していないのでGmailが使えません。

OCI8 / PDO_OCI

OCI8およびPDO_OCIは同梱されなくなりました。
当面はPECLからインストールできます。

OCIが使っているライブラリOracle Instant Clientは非常にバグが多く、使い物にならないそうです。

PSpell

PSpellは同梱されなくなりました。
当面はPECLからインストールできます。

PSpellが使っているライブラリpspellは、最終更新が2001年です。

Other Changes to Extensions

その他の変更。

Curl

The Curl extension now requires at least libcurl 7.61.0.

Curlエクステンションが要求する最低バージョンがlibcurl 7.61.0になりました。

The CURLOPT_DNS_USE_GLOBAL_CACHE Curl option no longer has any effect, and is silently ignored

CURLOPT_DNS_USE_GLOBAL_CACHEは黙って無視されます。

これはlibcurl側の変更に合わせたものです。
CURLOPT_DNS_USE_GLOBAL_CACHEはlibcurl 7.11.1で非推奨になり、libcurl 7.62.0で削除されました。

GMP

Casting a GMP object to bool is now possible instead of emitting a E_RECOVERABLE_ERROR

GMPオブジェクトをboolキャストできるようになりました
int型と同様0はfalse、それ以外は全てtrueです。

これまではE_RECOVERABLE_ERRORが発生していました。

Intl

The behaviour of Intl class has been normalized to always throw Error exceptions when attempting to use a non-initialized object

Intlクラスは、初期化せずに呼び出すとErrorを出すようになりました。
とあるんだけど何のことかわかんない。
non-initialized objectってなんだよ。

LibXML

The libxml extension now requires at least libxml2 2.9.4

libxmlエクステンションが要求する最低バージョンがlibxml2 2.9.4になりました。

MBString

Unicode data tables have been updated to Unicode 16.0

UnicodeテーブルがUnicode 16.0になりました。

Mysqlnd

Support for the new VECTOR data type from MySQL 9

MySQL 9.0以上でVECTOR型をサポートしました。

OpenSSL

The OpenSSL extension now requires at least OpenSSL 1.1.1

OpenSSLエクステンションが要求する最低バージョンがOpenSSL 1.1.1になりました。

OpenSSL1系は既にサポート終了しているので、できれば3にさっさと上げてしまうとよいでしょう。

PDO_PGSQL / PgSQL

The pdo_pgsql extension now requires at least libpq 10.0

pdo_pgsqlエクステンションが要求する最低バージョンがlibpq 10.0になりました。

SPL

Out of bounds accesses in SplFixedArray now throw an exception of type OutOfBoundsException instead of RuntimeException

SplFixedArrayで範囲外にアクセスした際のエラーがRuntimeExceptionからOutOfBoundsExceptionになりました。

ただしOutOfBoundsExceptionはRuntimeExceptionの子クラスなので、RuntimeExceptionをcatchしているコードはそのまま使えます。

XSL

The typed properties XSLTProcessor::$cloneDocument and XSLTProcessor::$doXInclude are now declared

プロパティXSLTProcessor::$cloneDocumentXSLTProcessor::$doXIncludeが実装されました。

zlib

The zlib extension now requires at least zlib 1.2.11

zlibエクステンションが要求する最低バージョンがzlib 1.2.11になりました。

New Global Constants

新しいグローバル定数。
基本的には使用しているライブラリで定義されている定数をそのまま取り込んだものです。

PHP_OUTPUT_HANDLER_PROCESSED
PHP_SBINDIR
CURL_HTTP_VERSION_3
CURL_HTTP_VERSION_3ONLY
CURL_TCP_KEEPCNT
CURLOPT_PREREQFUNCTION
CURL_PREREQFUNC_OK
CURL_PREREQFUNC_ABORT
CURLOPT_SERVER_RESPONSE_TIMEOUT
CURLOPT_DEBUGFUNCTION
CURLINFO_TEXT
CURLINFO_HEADER_IN
CURLINFO_DATA_IN
CURLINFO_DATA_OUT
CURLINFO_SSL_DATA_OUT
CURLINFO_SSL_DATA_IN
CURLINFO_POSTTRANSFER_TIME_T
IntlDateFormatter::PATTERN
IntlChar::PROPERTY_IDS_UNARY_OPERATOR
IntlChar::PROPERTY_ID_COMPAT_MATH_START
IntlChar::PROPERTY_ID_COMPAT_MATH_CONTINUE
LDAP_OPT_X_TLS_PROTOCOL_MAX
LDAP_OPT_X_TLS_PROTOCOL_TLS1_3
LIBXML_RECOVER
LIBXML_NO_XXE
MYSQLI_TYPE_VECTOR
X509_PURPOSE_OCSP_HELPER
X509_PURPOSE_TIMESTAMP_SIGN
Pcntl\QosClass::Background (macOs only)
Pcntl\QosClass::Default (macOs only)
Pctnl\QosClass::UserInteractive (macOs only)
Pcntl\QosClass::UserInitiated (macOs only)
Pcntl\QosClass::Utility (macOs only)
SIGCKPT (DragonFlyBSD only)
SIGCKPTEXIT (DragonFlyBSD only)
WEXITED
WSTOPPED
WNOWAIT
P_ALL
P_PID
P_PGID
P_PIDFD (Linux only)
P_UID (NetBSD/FreeBSD only)
P_GID (NetBSD/FreeBSD only)
P_SID (NetBSD/FreeBSD only)
P_JAILID (FreeBSD only)
PGSQL_TUPLES_CHUNK
POSIX_SC_CHILD_MAX
POSIX_SC_CLK_TCK
SO_EXCLUSIVEADDRUSE (Windows only)
SOCK_CONN_DGRAM (NetBSD only)
SOCK_DCCP (NetBSD only)
TCP_SYNCNT (Linux only)
SO_EXCLBIND (Solaris/Illumos only)
SO_NOSIGPIPE (macOs and FreeBSD)
SO_LINGER_SEC (macOs only)
IP_PORTRANGE (FreeBSD/NetBSD/OpenBSD only)
IP_PORTRANGE_DEFAULT (FreeBSD/NetBSD/OpenBSD only)
IP_PORTRANGE_HIGH (FreeBSD/NetBSD/OpenBSD only)
IP_PORTRANGE_LOW (FreeBSD/NetBSD/OpenBSD only)
SOCK_NONBLOCK
SOCK_CLOEXEC
SO_BINDTOIFINDEX
SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES
SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES
SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES
SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES
SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES
SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES
SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES
SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES
XML_OPTION_PARSE_HUGE

Windows Support

Windowsサポートについて。

Building with Visual Studio now requires at least Visual Studio 2019

Windowsでのビルドには、Visual Studio 2019以上が必要です。
Visual Studio 2022以上が推奨されています。

AVX(2) CPU support is now properly detected for MSVC builds.

CPU拡張命令AVX・AVX2のサポートを適切に検出できるようになりました。

Native AVX-512 builds are now supported

CPU命令セットAVX-512がサポートされました。
コンパイルオプション--enable-native-intrinsics=avx512で有効化されます。

Other Changes

その他の変更。

Closure names have been adjusted to include the parent function's name and the line of definition

クロージャにファイル名や定義行が含まれるようになりました。

$c = function(){return 1;};
var_dump($c);

// PHP8.4 object(Closure)#1 (3) { "name"=>"path/to/file:10", "file"=>"path/to/file", "line"=>10 }
// PHP8.3 object(Closure)#1 (0) {}

これによってデバッグやスタックトレースの確認がやりやすくなります。

run-tests.php now skips online tests by default

run-tests.phpはオンラインテストをスキップするようになりました。

そもそもrun-tests.phpって何かというとPHPに用意されているテストランナーです。
環境変数SKIP_ONLINE_TESTSを0にするとオンラインテストも実行されます。

Fiber switching during destructor execution is now allowed

デストラクタ中でFiberの切り替えが可能になりました。
これまではできませんでした。

01.png

Performance Improvements

パフォーマンスの改善。

BCMath

Improved performance of number conversions and operations

数値変換、演算のパフォーマンスが向上しました。

除算が10倍速くなったなど、相当な高速化がなされたようです。

Core

Improved the performance of floating point number parsing and formatting in ZTS builds under highly concurrent loads

スレッドセーフ実装であるZTSビルドにおいて、浮動小数点のパフォーマンスが向上しました。
serialize()serialize()等に効果があります。

私はいつもVS17 x64 Thread SafeつまりZTSのバージョンをダウンロードしているのですが、正直ZTSとNTSがどう違うのかわかりません

sprintf() using only %s and %d will be compiled into the equivalent string interpolation

%s%dしか使っていないsprintf()は関数呼び出しが不要な形にコンパイルされます。
これによって関数呼び出しのオーバーヘッドがなくなります。

DOM

The performance of DOMNode::C14N() is greatly improved for the case without an xpath query

XPathクエリがない場合、DOMNode::C14N()のパフォーマンスが2桁上昇します。
2桁ってどんだけだよ。

Improved performance and reduce memory consumption of XML serialization.

XMLシリアル化のメモリ消費量が削減され、パフォーマンスも向上しました。

Reduced memory usage of node classes

Nodeクラスのメモリ使用量を削減しました。

FTP

Improved the performance of FTP uploads up to a factor of 10x for large uploads

大容量ファイルをFTPアップロードする際のパフォーマンスが、最大10倍ほど向上しました。

Hash

Added SSE2 and SHA-NI implementations of SHA-256

SHA-256について、SSE2とSHA-NIを実装しました。
SSE2対応CPUであれば1.3倍、SHA-NI対応CPUであれば3から5倍高速化します。

MBString

mb_strcut() is much faster now for UTF-8 and UTF-16 strings

UTF-8およびUTF-16文字列のmb_strcut()が大幅に高速化されました。

Looking up mbstring encoding names is much faster now

マルチバイト文字のエンコーディング名検索が大幅に高速化されました。

The performance of converting SJIS-win to unicode is greatly improved

SJIS-winからUnicodeへの変換性能が大幅に向上しました。

MySQLnd

Improved the performance of MySQLnd quoting

MySQLndのquoting性能が向上しました。

quotingってなに?
まさかmysqli::real_escape_string()のこと…ではないよねえ?

PCRE

Improved the performance of named capture groups

名前付きキャプチャグループのパフォーマンスが向上しました。

Random

Improved the performance of \Random\Randomizer, with a specific focus on the getBytes() and getBytesFromString() methods

\Random\Randomizerのパフォーマンスが向上しました。
特によく使われるであろうRandom\Randomizer::getBytes()Random\Randomizer::getBytesFromString()を重点的に改善しています。

SimpleXML

Improved performance and reduce memory consumption of XML serialization

XMLシリアル化のメモリ消費量が削減され、パフォーマンスも向上しました。

たぶん中身がDOMと同じなんじゃないかな。

Standard

Improved the performance of strpbrk()

strpbrk()のパフォーマンスが向上しました。

strposしか使ったことないわ。

The performance of strspn() and strcspn() is greatly improved

strspn()strcspn()のパフォーマンスが大幅に向上しました。

これまでO(n^2)だったのがO(n)になりました。

get_browser() is much faster now, up to 1.5x - 2.5x for some test cases.

get_browser()のパフォーマンスが向上しました。

1.5から2.5倍くらいになりました。

感想

長い。

相変わらずものすごい数の変更・改善が入っています。
これを毎年、マイナーバージョンのバグ修正もしっかりこなしながら出してくるのだから恐れ入りますね。

PHP8.4の目玉は、なんといってもやはりプロパティフック非対称可視性でしょう。
PHP7あたりからどんどん追加されてきたこれらの機能によって、PHPはもはや下手な言語よりがっちりと型安全性を意識したコーディングが可能になります。
もちろん動的言語の限界はあるのでがんばればどうにかできないこともないですが、余計なことをせずVSCode+PHP Intelephense+Laravelあたりで普通に使っている限りでは、もう静的言語並みに型安全に書けます。
いやーかつてのPHP5時代とは本当に天地の差がありますよ。

さらにmbstringに便利機能が増えた配列検索がやりやすくなったnewの括弧が不要になったといった地道な改善もたくさん行われています。

また、PHP8.3から互換性のない変更はほとんどありません。
下位互換性のない変更点を見るかぎりではわりとあるように見えますが、はっきりいって普通の使い方をしている限りではほぼ遭遇しないものばかりです。

ということで、さらに使いやすく便利で高性能になったPHP8.4、是非導入して使ってみましょう。

32
12
1

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
32
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?