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
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->languageCode, $this->countryCode] = 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
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}";
}
}
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
ドキュメント
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();
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 = 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)
$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\HTMLDocument
と Dom\XMLDocument
クラスを利用して作成できます。
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);
echo $result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
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
$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"
$animal = array_find(
['dog', 'cat', 'cow', 'duck', 'goose'],
static fn (string $value): bool => str_starts_with($value, 'c'),
);
var_dump($animal); // string(3) "cat"
$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');
$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\Dblib
、Pdo\Firebird
、Pdo\MySql
、Pdo\Odbc
、Pdo\Pgsql
、Pdo\Sqlite
が追加されました。 new MyClass()->method()
RFC
ドキュメント
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.3';
}
}
var_dump((new PhpVersion())->getVersion());
class PhpVersion
{
public function getVersion(): string
{
return 'PHP 8.4';
}
}
var_dump(new PhpVersion()->getVersion());
new
式を括弧で囲むことなくできるようになります。 request_parse_body()
関数bcceil()
、bcdivmod()
、bcfloor()
、bcround()
関数round()
関数の新しい4つの丸めモード TowardsZero
、AwayFromZero
、NegativeInfinity
、PositiveInfinity
のための 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()
関数_
を使うことは非推奨になりました。round()
に無効なモードを渡すと ValueError
がスローされます。date
、intl
、pdo
、reflection
、spl
、sqlite
、xmlreader
拡張モジュールのクラス定数に型宣言が追加されました。GMP
クラスは final になりました。MYSQLI_SET_CHARSET_DIR
、MYSQLI_STMT_ATTR_PREFETCH_ROWS
、MYSQLI_CURSOR_TYPE_FOR_UPDATE
、MYSQLI_CURSOR_TYPE_SCROLLABLE
、MYSQLI_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
定数は非推奨になりました。