PHP 8.4.1 Released!
リリース!
PHP 8.4 は、PHP 言語のメジャーアップデートです。
プロパティフック、非対称可視性、新しい DOM API などの新機能や、パフォーマンス改善、バグ修正やコードのクリーンアップが含まれています。

プロパティフック RFC ドキュメント

PHP < 8.4
class Locale
{
private
string $languageCode;
private
string $countryCode;

public function
__construct(string $languageCode, string $countryCode)
{
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getLanguageCode(): string
{
return
$this->languageCode;
}

public function
setLanguageCode(string $languageCode): void
{
$this->languageCode = $languageCode;
}

public function
getCountryCode(): string
{
return
$this->countryCode;
}

public function
setCountryCode(string $countryCode): void
{
$this->countryCode = strtoupper($countryCode);
}

public function
setCombinedCode(string $combinedCode): void
{
[
$languageCode, $countryCode] = explode('_', $combinedCode, 2);

$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getCombinedCode(): string
{
return
\sprintf("%s_%s", $this->languageCode, $this->countryCode);
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->getCountryCode()); // BR
var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR
PHP 8.4
class Locale
{
public
string $languageCode;

public
string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}

public
string $combinedCode
{
get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[
$this->countryCode, $this->languageCode] = explode('_', $value, 2);
}
}

public function
__construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR
プロパティフックは算出プロパティの機能を提供します。実態とずれやすい docblock コメントを書かずとも、IDEや静的解析ツールがネイティブに理解してくれます。さらに、対応するゲッターやセッターがそのクラスに存在するか確認することなく、確実に値の前処理・後処理を行うことができます。

非対称可視性 RFC ドキュメント

PHP < 8.4
class PhpVersion
{
private
string $version = '8.3';

public function
getVersion(): string
{
return
$this->version;
}

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
PHP 8.4
class PhpVersion
{
public private(
set) string $version = '8.4';

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
プロパティへの書き込みのスコープが、読み込みのスコープと独立して制御できるようになります。これによって、クラス外からのプロパティの変更を防ぎ値の取得のみを行えるゲッターメソッドのボイラープレートを書く必要がなくなります。

#[\Deprecated] アトリビュート RFC ドキュメント

PHP < 8.4
class PhpVersion
{
/**
* @deprecated 8.3 use PhpVersion::getVersion() instead
*/
public function getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.3';
}
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();
PHP 8.4
class PhpVersion
{
#[
\Deprecated(
message: "use PhpVersion::getVersion() instead",
since: "8.4",
)]
public function
getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.4';
}
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();
新しい #[\Deprecated] アトリビュートを使うと、PHP の既存の非推奨機構をユーザー定義の関数、メソッド、クラス定数で利用できるようになります。

DOM 拡張モジュールの新機能と HTML5 サポート RFC RFC ドキュメント

PHP < 8.4
$dom = new DOMDocument();
$dom->loadHTML(
<<<'HTML'
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)
PHP 8.4
$dom = Dom\HTMLDocument::createFromString(
<<<HTML
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)

新しい DOM API では、標準に沿った HTML5 ドキュメントのパース機能が追加され、古くからある標準に準拠しない複数の DOM 機能の振る舞いに関する不具合が修正され、ドキュメントの操作がより便利になるいくつかの関数が追加されました。

新しい DOM API は Dom 名前空間で利用できます。新しい DOM API を利用するドキュメントは Dom\HTMLDocumentDom\XMLDocument クラスを利用して作成できます。

BCMath のオブジェクト API RFC

PHP < 8.4
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo
$result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
PHP 8.4
use BcMath\Number;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo
$result; // '2.12345'
var_dump($num1 > $num2); // false

新しい BcMath\Number オブジェクトを使うと、任意精度数値をオブジェクト指向で利用したり、通常の算術演算子で計算したりできるようになります。

このオブジェクトはイミュータブルで、 Stringable インターフェースを実装しているので echo $num のように文字列の文脈で利用可能です。

新しい array_*() 関数 RFC

PHP < 8.4
$animal = null;
foreach ([
'dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
if (
str_starts_with($value, 'c')) {
$animal = $value;
break;
}
}

var_dump($animal); // string(3) "cat"
PHP 8.4
$animal = array_find(
[
'dog', 'cat', 'cow', 'duck', 'goose'],
static fn (
string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"
新しい関数 array_find()array_find_key()array_any()array_all() が追加されました。

PDO ドライバー固有のサブクラス RFC

PHP < 8.4
$connection = new PDO(
'sqlite:foo.db',
$username,
$password,
);
// object(PDO)

$connection->sqliteCreateFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);

$connection->query('SELECT prepend_php(version) FROM php');
PHP 8.4
$connection = PDO::connect(
'sqlite:foo.db',
$username,
$password,
);
// object(Pdo\Sqlite)

$connection->createFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);
// Does not exist on a mismatching driver.

$connection->query('SELECT prepend_php(version) FROM php');
新しい PDO のサブクラス Pdo\DblibPdo\FirebirdPdo\MySqlPdo\OdbcPdo\PgsqlPdo\Sqlite が追加されました。

括弧なしの new MyClass()->method() RFC ドキュメント

PHP < 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.3';
}
}

var_dump((new PhpVersion())->getVersion());
PHP 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.4';
}
}

var_dump(new PhpVersion()->getVersion());
新しくインスタンス化されたオブジェクトのプロパティとメソッドへのアクセスが、new 式を括弧で囲むことなくできるようになります。

新しいクラス、インターフェイス、関数

  • レイジーオブジェクト
  • IR フレームワークベースの新しい JIT 実装
  • request_parse_body() 関数
  • bcceil()bcdivmod()bcfloor()bcround() 関数
  • round() 関数の新しい4つの丸めモード TowardsZeroAwayFromZeroNegativeInfinityPositiveInfinity のための RoundingMode 列挙型
  • DateTime::createFromTimestamp()DateTime::getMicrosecond()DateTime::setMicrosecond()DateTimeImmutable::createFromTimestamp()DateTimeImmutable::getMicrosecond()DateTimeImmutable::setMicrosecond() メソッド
  • mb_trim()mb_ltrim()mb_rtrim()mb_ucfirst()mb_lcfirst() 関数
  • pcntl_getcpu()pcntl_getcpuaffinity()pcntl_getqos_class()pcntl_setns()pcntl_waitid() 関数
  • ReflectionClassConstant::isDeprecated()ReflectionGenerator::isClosed()ReflectionProperty::isDynamic() メソッド
  • http_get_last_response_headers()http_clear_last_response_headers()fpow() 関数
  • XMLReader::fromStream()XMLReader::fromUri()XMLReader::fromString()XMLWriter::toStream()XMLWriter::toUri()XMLWriter::toMemory() メソッド
  • grapheme_str_split() 関数

非推奨、および互換性のない変更

  • IMAP、OCI8、PDO_OCI、pspell 拡張モジュールが PHP 本体から削除され、PECL に移動されました。
  • 暗黙の nullable 型パラメータが非推奨になりました。
  • クラス名として _ を使うことは非推奨になりました。
  • ゼロの負の数のべき乗は非推奨になりました。
  • round() に無効なモードを渡すと ValueError がスローされます。
  • dateintlpdoreflectionsplsqlitexmlreader 拡張モジュールのクラス定数に型宣言が追加されました。
  • GMP クラスは final になりました。
  • 定数 MYSQLI_SET_CHARSET_DIRMYSQLI_STMT_ATTR_PREFETCH_ROWSMYSQLI_CURSOR_TYPE_FOR_UPDATEMYSQLI_CURSOR_TYPE_SCROLLABLEMYSQLI_TYPE_INTERVAL が削除されました。
  • mysqli_ping()mysqli_kill()mysqli_refresh() 関数、mysqli::ping()mysqli::kill()mysqli::refresh() メソッド、MYSQLI_REFRESH_* 定数は非推奨になりました。
  • stream_bucket_make_writeable()stream_bucket_new() の戻り値は stdClass ではなく StreamBucket になりました。
  • exit() の挙動が変更されました
  • E_STRICT 定数は非推奨になりました。
To Top