classLocale{ privatestring$languageCode; privatestring$countryCode; public function__construct(string$languageCode,string$countryCode) {$this->setLanguageCode($languageCode);$this->setCountryCode($countryCode); } public functiongetLanguageCode():string{ return$this->languageCode; } public functionsetLanguageCode(string$languageCode):void{$this->languageCode=$languageCode; } public functiongetCountryCode():string{ return$this->countryCode; } public functionsetCountryCode(string$countryCode):void{$this->countryCode=strtoupper($countryCode); } public functionsetCombinedCode(string$combinedCode):void{ [$languageCode,$countryCode] =explode('_',$combinedCode,2);$this->setLanguageCode($languageCode);$this->setCountryCode($countryCode); } public functiongetCombinedCode():string{ return\sprintf("%s_%s",$this->languageCode,$this->countryCode); }}$brazilianPortuguese= newLocale('pt','br');var_dump($brazilianPortuguese->getCountryCode());// BRvar_dump($brazilianPortuguese->getCombinedCode());// pt_BRclassLocale{ publicstring$languageCode; publicstring$countryCode{set(string$countryCode) {$this->countryCode=strtoupper($countryCode); } } publicstring$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= newLocale('pt','br');var_dump($brazilianPortuguese->countryCode);// BRvar_dump($brazilianPortuguese->combinedCode);// pt_BRclassPhpVersion{ privatestring$version='8.3'; public functiongetVersion():string{ return$this->version; } public functionincrement():void{ [$major,$minor] =explode('.',$this->version);$minor++;$this->version="{$major}.{$minor}"; }}classPhpVersion{ public private(set)string$version='8.4'; public functionincrement():void{ [$major,$minor] =explode('.',$this->version);$minor++;$this->version="{$major}.{$minor}"; }}#[\Deprecated] AttributeRFCDocclassPhpVersion{/** * @deprecated 8.3 use PhpVersion::getVersion() instead */public functiongetPhpVersion():string{ return$this->getVersion(); } public functiongetVersion():string{ return'8.3'; }}$phpVersion= newPhpVersion();// No indication that the method is deprecated.echo$phpVersion->getPhpVersion();classPhpVersion{ #[\Deprecated(message:"use PhpVersion::getVersion() instead",since:"8.4", )] public functiongetPhpVersion():string{ return$this->getVersion(); } public functiongetVersion():string{ return'8.4'; }}$phpVersion= newPhpVersion();// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() insteadecho$phpVersion->getPhpVersion();#[\Deprecated] attribute makes PHP’s existing deprecation mechanism available to user-defined functions, methods, and class constants.$dom= newDOMDocument();$dom->loadHTML( <<<'HTML' <main> <article>PHP 8.4 is a feature-rich release!</article> <article>PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article> </main> HTML,LIBXML_NOERROR,);$xpath= newDOMXPath($dom);$node=$xpath->query(".//main/article[not(following-sibling::*)]")[0];$classes=explode(" ",$node->className);// Simplifiedvar_dump(in_array("featured",$classes));// bool(true)$dom=Dom\HTMLDocument::createFromString( <<<'HTML' <main> <article>PHP 8.4 is a feature-rich release!</article> <article>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)New DOM API that includes standards-compliant support for parsing HTML5 documents, fixes several long-standing compliance bugs in the behavior of the DOM functionality, and adds several functions to make working with documents more convenient.
The new DOM API is available within theDom namespace. Documents using the new DOM API can be created using theDom\HTMLDocument andDom\XMLDocument classes.
$num1='0.12345';$num2='2';$result=bcadd($num1,$num2,5);echo$result;// '2.12345'var_dump(bccomp($num1,$num2) >0);// falseuseBcMath\Number;$num1= newNumber('0.12345');$num2= newNumber('2');$result=$num1+$num2;echo$result;// '2.12345'var_dump($num1>$num2);// falseNewBcMath\Number object enables object-oriented usage and standard mathematical operators when working with arbitrary precision numbers.
These objects are immutable and implement theStringable interface, so they can be used in string contexts likeecho $num.
array_*() functionsRFC$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= newPDO('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\Dblib,Pdo\Firebird,Pdo\MySql,Pdo\Odbc,Pdo\Pgsql, andPdo\Sqlite ofPDO are available.new MyClass()->method() without parenthesesRFCDocclassPhpVersion{ public functiongetVersion():string{ return'PHP 8.3'; }}var_dump((newPhpVersion())->getVersion());classPhpVersion{ public functiongetVersion():string{ return'PHP 8.4'; }}var_dump(newPhpVersion()->getVersion());new expression in parentheses.request_parse_body() function.bcceil(),bcdivmod(),bcfloor(), andbcround() functions.RoundingMode enum forround() with 4 new rounding modesTowardsZero,AwayFromZero,NegativeInfinity, andPositiveInfinity.DateTime::createFromTimestamp(),DateTime::getMicrosecond(),DateTime::setMicrosecond(),DateTimeImmutable::createFromTimestamp(),DateTimeImmutable::getMicrosecond(), andDateTimeImmutable::setMicrosecond() methods.mb_trim(),mb_ltrim(),mb_rtrim(),mb_ucfirst(), andmb_lcfirst() functions.pcntl_getcpu(),pcntl_getcpuaffinity(),pcntl_getqos_class(),pcntl_setns(), andpcntl_waitid() functions.ReflectionClassConstant::isDeprecated(),ReflectionGenerator::isClosed(), andReflectionProperty::isDynamic() methods.http_get_last_response_headers(),http_clear_last_response_headers(), andfpow() functions.XMLReader::fromStream(),XMLReader::fromUri(),XMLReader::fromString(),XMLWriter::toStream(),XMLWriter::toUri(), andXMLWriter::toMemory() methods.grapheme_str_split() function._ as a class name is now deprecated.round() throwsValueError.date,intl,pdo,reflection,spl,sqlite,xmlreader are typed now.GMP class is now final.MYSQLI_SET_CHARSET_DIR,MYSQLI_STMT_ATTR_PREFETCH_ROWS,MYSQLI_CURSOR_TYPE_FOR_UPDATE,MYSQLI_CURSOR_TYPE_SCROLLABLE, andMYSQLI_TYPE_INTERVAL constants have been removed.mysqli_ping(),mysqli_kill(),mysqli_refresh() functions,mysqli::ping(),mysqli::kill(),mysqli::refresh() methods, andMYSQLI_REFRESH_* constants have been deprecated.stream_bucket_make_writeable() andstream_bucket_new() now return an instance ofStreamBucket instead ofstdClass.exit() behavioral change.E_STRICT constant has been deprecated.For source downloads of PHP 8.4 please visit thedownloads page. Windows binaries can be found on thePHP for Windows site. The list of changes is recorded in theChangeLog.
Themigration guide is available in the PHP Manual. Please consult it for a detailed list of new features and backward-incompatible changes.
