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_BRclass 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_BRclass 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 请使用 PhpVersion::getVersion() 代替
*/
public function getPhpVersion(): string
{
return $this->getVersion();
}
public function getVersion(): string
{
return '8.3';
}
}
$phpVersion = new PhpVersion();
// 没有提示方法已弃用。
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 是一个功能丰富的版本!</article>
<article class="featured">PHP 8.4 添加了新的符合规范的 DOM 类,并保留旧类以保持兼容性。</article>
</main>
HTML,
LIBXML_NOERROR,
);
$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // 简化
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); // falseuse 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}",
); // 在不匹配的驱动程序上不存在。
$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() 新增 RoundingMode 枚举,并包含 4 种新的舍入模式:TowardsZero、AwayFromZero、NegativeInfinity 和 PositiveInfinity。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 类现在是最终类。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() 现在返回 StreamBucket 实例,而不是 stdClass。exit() 行为更改.E_STRICT 常量。