1<?php 2 3use function releases\php84\common_header;use function releases\php84\language_chooser;use function releases\php84\message; 4 5if (!isset($lang)) { 6 $lang = 'en'; 7} 8if (!isset($documentation)) { 9 $documentation = $lang; 10} 11 12$_SERVER['BASE_PAGE'] = 'releases/8.4/' . $lang . '.php'; 13 14include_once __DIR__ . '/common.php'; 15 16common_header(message('common_header', $lang)); 17 18?> 19 <section class="php8-section php8-section_dark php8-section_header center"> 20 <div class="page-tools"> 21 <div class="change-language"> 22 <?php language_chooser($lang); ?> 23 </div> 24 </div> 25 <div class="php8-section__content"> 26 <div class="php8-logo"> 27 <img src="/images/php8/logo_php8_4.svg" alt="PHP 8.4" height="126" width="343"> 28 </div> 29 <div class="php8-title"><?= message('main_title', $lang) ?></div> 30 <div class="php8-subtitle"><?= message('main_subtitle', $lang) ?></div> 31 <div class="php8-button-wrapper center"> 32 <a class="php8-button php8-button_light" href="/downloads"><?= message('upgrade_now', $lang) ?></a> 33 </div> 34 </div> 35 </section> 36 37 <section class="php8-section center"> 38 <div class="php8-compare"> 39 <h2 class="php8-h2" id="property_hooks"> 40 <?= message('property_hooks_title', $lang) ?> 41 <a class="php8-rfc" href="https://wiki.php.net/rfc/property-hooks">RFC</a> 42 <a class="php8-rfc" href="/manual/<?= $documentation ?>/migration84.new-features.php#migration84.new-features.core.property-hooks"><?= message('documentation', $lang) ?></a> 43 </h2> 44 <div class="php8-compare__main"> 45 <div class="php8-compare__block example-contents"> 46 <div class="php8-compare__label">PHP < 8.4</div> 47 <div class="php8-code phpcode"> 48 <?php highlight_php_trimmed( 49 <<<'PHP' 50class Locale 51{ 52 private string $languageCode; 53 private string $countryCode; 54 55 public function __construct(string $languageCode, string $countryCode) 56 { 57 $this->setLanguageCode($languageCode); 58 $this->setCountryCode($countryCode); 59 } 60 61 public function getLanguageCode(): string 62 { 63 return $this->languageCode; 64 } 65 66 public function setLanguageCode(string $languageCode): void 67 { 68 $this->languageCode = $languageCode; 69 } 70 71 public function getCountryCode(): string 72 { 73 return $this->countryCode; 74 } 75 76 public function setCountryCode(string $countryCode): void 77 { 78 $this->countryCode = strtoupper($countryCode); 79 } 80 81 public function setCombinedCode(string $combinedCode): void 82 { 83 [$languageCode, $countryCode] = explode('_', $combinedCode, 2); 84 85 $this->setLanguageCode($languageCode); 86 $this->setCountryCode($countryCode); 87 } 88 89 public function getCombinedCode(): string 90 { 91 return \sprintf("%s_%s", $this->languageCode, $this->countryCode); 92 } 93} 94 95$brazilianPortuguese = new Locale('pt', 'br'); 96var_dump($brazilianPortuguese->getCountryCode()); // BR 97var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR 98PHP 99 100 ); ?> 101 </div> 102 </div> 103 <div class="php8-compare__arrow"></div> 104 <div class="php8-compare__block example-contents" style="display: table;"> 105 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 106 <div class="php8-code phpcode" style="display: table-cell;"> 107 <?php highlight_php_trimmed( 108 <<<'PHP' 109class Locale 110{ 111 public string $languageCode; 112 113 public string $countryCode 114 { 115 set (string $countryCode) { 116 $this->countryCode = strtoupper($countryCode); 117 } 118 } 119 120 public string $combinedCode 121 { 122 get => \sprintf("%s_%s", $this->languageCode, $this->countryCode); 123 set (string $value) { 124 [$this->countryCode, $this->languageCode] = explode('_', $value, 2); 125 } 126 } 127 128 public function __construct(string $languageCode, string $countryCode) 129 { 130 $this->languageCode = $languageCode; 131 $this->countryCode = $countryCode; 132 } 133} 134 135$brazilianPortuguese = new Locale('pt', 'br'); 136var_dump($brazilianPortuguese->countryCode); // BR 137var_dump($brazilianPortuguese->combinedCode); // pt_BR 138PHP 139 ); ?> 140 </div> 141 </div> 142 </div> 143 <div class="php8-compare__content"> 144 <?= message('property_hooks_description', $lang) ?> 145 </div> 146 </div> 147 <div class="php8-compare"> 148 <h2 class="php8-h2" id="asymmetric_visibility"> 149 <?= message('asymmetric_visibility_title', $lang) ?> 150 <a class="php8-rfc" href="https://wiki.php.net/rfc/asymmetric-visibility-v2">RFC</a> 151 <a class="php8-rfc" href="/manual/<?= $documentation ?>/language.oop5.visibility.php#language.oop5.visibility-members-aviz"><?= message('documentation', $lang) ?></a> 152 </h2> 153 <div class="php8-compare__main"> 154 <div class="php8-compare__block example-contents"> 155 <div class="php8-compare__label">PHP < 8.4</div> 156 <div class="php8-code phpcode"> 157 <?php highlight_php_trimmed( 158 <<<'PHP' 159class PhpVersion 160{ 161 private string $version = '8.3'; 162 163 public function getVersion(): string 164 { 165 return $this->version; 166 } 167 168 public function increment(): void 169 { 170 [$major, $minor] = explode('.', $this->version); 171 $minor++; 172 $this->version = "{$major}.{$minor}"; 173 } 174} 175PHP 176 177 ); ?> 178 </div> 179 </div> 180 <div class="php8-compare__arrow"></div> 181 <div class="php8-compare__block example-contents"> 182 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 183 <div class="php8-code phpcode"> 184 <?php highlight_php_trimmed( 185 <<<'PHP' 186class PhpVersion 187{ 188 public private(set) string $version = '8.4'; 189 190 public function increment(): void 191 { 192 [$major, $minor] = explode('.', $this->version); 193 $minor++; 194 $this->version = "{$major}.{$minor}"; 195 } 196} 197PHP 198 ); ?> 199 </div> 200 </div> 201 </div> 202 <div class="php8-compare__content"> 203 <?= message('asymmetric_visibility_description', $lang) ?> 204 </div> 205 </div> 206 <div class="php8-compare"> 207 <h2 class="php8-h2" id="deprecated_attribute"> 208 <?= message('deprecated_attribute_title', $lang) ?> 209 <a class="php8-rfc" href="https://wiki.php.net/rfc/deprecated_attribute">RFC</a> 210 <a class="php8-rfc" href="/manual/<?= $documentation ?>/class.deprecated.php"><?= message('documentation', $lang) ?></a> 211 </h2> 212 <div class="php8-compare__main"> 213 <div class="php8-compare__block example-contents"> 214 <div class="php8-compare__label">PHP < 8.4</div> 215 <div class="php8-code phpcode"> 216 <?php highlight_php_trimmed( 217 <<<'PHP' 218class PhpVersion 219{ 220 /** 221 * @deprecated 8.3 use PhpVersion::getVersion() instead 222 */ 223 public function getPhpVersion(): string 224 { 225 return $this->getVersion(); 226 } 227 228 public function getVersion(): string 229 { 230 return '8.3'; 231 } 232} 233 234$phpVersion = new PhpVersion(); 235// No indication that the method is deprecated. 236echo $phpVersion->getPhpVersion(); 237PHP 238 239 ); ?> 240 </div> 241 </div> 242 <div class="php8-compare__arrow"></div> 243 <div class="php8-compare__block example-contents"> 244 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 245 <div class="php8-code phpcode"> 246 <?php highlight_php_trimmed( 247 <<<'PHP' 248class PhpVersion 249{ 250 #[\Deprecated( 251 message: "use PhpVersion::getVersion() instead", 252 since: "8.4", 253 )] 254 public function getPhpVersion(): string 255 { 256 return $this->getVersion(); 257 } 258 259 public function getVersion(): string 260 { 261 return '8.4'; 262 } 263} 264 265$phpVersion = new PhpVersion(); 266// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead 267echo $phpVersion->getPhpVersion(); 268PHP 269 ); ?> 270 </div> 271 </div> 272 </div> 273 <div class="php8-compare__content"> 274 <?= message('deprecated_attribute_description', $lang) ?> 275 </div> 276 </div> 277 <div class="php8-compare"> 278 <h2 class="php8-h2" id="dom_additions_html5"> 279 <?= message('dom_additions_html5_title', $lang) ?> 280 <a class="php8-rfc" href="https://wiki.php.net/rfc/dom_additions_84">RFC</a> 281 <a class="php8-rfc" href="https://wiki.php.net/rfc/domdocument_html5_parser">RFC</a> 282 <a class="php8-rfc" href="/manual/<?= $documentation ?>/migration84.new-features.php#migration84.new-features.dom"><?= message('documentation', $lang) ?></a> 283 </h2> 284 <div class="php8-compare__main"> 285 <div class="php8-compare__block example-contents"> 286 <div class="php8-compare__label">PHP < 8.4</div> 287 <div class="php8-code phpcode"> 288 <?php highlight_php_trimmed( 289 <<<'PHP' 290$dom = new DOMDocument(); 291$dom->loadHTML( 292 <<<'HTML' 293 <main> 294 <article>PHP 8.4 is a feature-rich release!</article> 295 <article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article> 296 </main> 297 HTML, 298 LIBXML_NOERROR, 299); 300 301$xpath = new DOMXPath($dom); 302$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0]; 303$classes = explode(" ", $node->className); // Simplified 304var_dump(in_array("featured", $classes)); // bool(true) 305PHP 306 307 ); ?> 308 </div> 309 </div> 310 <div class="php8-compare__arrow"></div> 311 <div class="php8-compare__block example-contents"> 312 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 313 <div class="php8-code phpcode"> 314 <?php highlight_php_trimmed( 315 <<<'PHP' 316$dom = Dom\HTMLDocument::createFromString( 317 <<<HTML 318 <main> 319 <article>PHP 8.4 is a feature-rich release!</article> 320 <article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article> 321 </main> 322 HTML, 323 LIBXML_NOERROR, 324); 325 326$node = $dom->querySelector('main > article:last-child'); 327var_dump($node->classList->contains("featured")); // bool(true) 328PHP 329 ); ?> 330 </div> 331 </div> 332 </div> 333 <div class="php8-compare__content"> 334 <?= message('dom_additions_html5_description', $lang) ?> 335 </div> 336 </div> 337 <div class="php8-compare"> 338 <h2 class="php8-h2" id="bcmath"> 339 <?= message('bcmath_title', $lang) ?> 340 <a class="php8-rfc" href="https://wiki.php.net/rfc/support_object_type_in_bcmath">RFC</a> 341 </h2> 342 <div class="php8-compare__main"> 343 <div class="php8-compare__block example-contents"> 344 <div class="php8-compare__label">PHP < 8.4</div> 345 <div class="php8-code phpcode"> 346 <?php highlight_php_trimmed( 347 <<<'PHP' 348$num1 = '0.12345'; 349$num2 = 2; 350$result = bcadd($num1, $num2, 5); 351 352echo $result; // '2.12345' 353var_dump(bccomp($num1, $num2) > 0); // false 354PHP 355 356 ); ?> 357 </div> 358 </div> 359 <div class="php8-compare__arrow"></div> 360 <div class="php8-compare__block example-contents"> 361 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 362 <div class="php8-code phpcode"> 363 <?php highlight_php_trimmed( 364 <<<'PHP' 365use BcMath\Number; 366 367$num1 = new Number('0.12345'); 368$num2 = new Number('2'); 369$result = $num1 + $num2; 370 371echo $result; // '2.12345' 372var_dump($num1 > $num2); // false 373PHP 374 ); ?> 375 </div> 376 </div> 377 </div> 378 <div class="php8-compare__content"> 379 <?= message('bcmath_description', $lang) ?> 380 </div> 381 </div> 382 <div class="php8-compare"> 383 <h2 class="php8-h2" id="new_array_find"> 384 <?= message('new_array_find_title', $lang) ?> 385 <a class="php8-rfc" href="https://wiki.php.net/rfc/array_find">RFC</a> 386 </h2> 387 <div class="php8-compare__main"> 388 <div class="php8-compare__block example-contents"> 389 <div class="php8-compare__label">PHP < 8.4</div> 390 <div class="php8-code phpcode"> 391 <?php highlight_php_trimmed( 392 <<<'PHP' 393$animal = null; 394foreach (['dog', 'cat', 'cow', 'duck', 'goose'] as $value) { 395 if (str_starts_with($value, 'c')) { 396 $animal = $value; 397 break; 398 } 399} 400 401var_dump($animal); // string(3) "cat" 402PHP 403 ); ?> 404 </div> 405 </div> 406 <div class="php8-compare__arrow"></div> 407 <div class="php8-compare__block example-contents"> 408 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 409 <div class="php8-code phpcode"> 410 <?php highlight_php_trimmed( 411 <<<'PHP' 412$animal = array_find( 413 ['dog', 'cat', 'cow', 'duck', 'goose'], 414 static fn (string $value): bool => str_starts_with($value, 'c'), 415); 416 417var_dump($animal); // string(3) "cat" 418PHP 419 ); ?> 420 </div> 421 </div> 422 </div> 423 <div class="php8-compare__content"> 424 <?= message('new_array_find_description', $lang) ?> 425 </div> 426 </div> 427 <div class="php8-compare"> 428 <h2 class="php8-h2" id="pdo_driver_specific_subclasses"> 429 <?= message('pdo_driver_specific_subclasses_title', $lang) ?> 430 <a class="php8-rfc" href="https://wiki.php.net/rfc/pdo_driver_specific_subclasses">RFC</a> 431 </h2> 432 <div class="php8-compare__main"> 433 <div class="php8-compare__block example-contents"> 434 <div class="php8-compare__label">PHP < 8.4</div> 435 <div class="php8-code phpcode"> 436 <?php highlight_php_trimmed( 437 <<<'PHP' 438$connection = new PDO( 439 'sqlite:foo.db', 440 $username, 441 $password, 442); // object(PDO) 443 444$connection->sqliteCreateFunction( 445 'prepend_php', 446 static fn ($string) => "PHP {$string}", 447); 448 449$connection->query('SELECT prepend_php(version) FROM php'); 450PHP 451 ); ?> 452 </div> 453 </div> 454 <div class="php8-compare__arrow"></div> 455 <div class="php8-compare__block example-contents"> 456 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 457 <div class="php8-code phpcode"> 458 <?php highlight_php_trimmed( 459 <<<'PHP' 460$connection = PDO::connect( 461 'sqlite:foo.db', 462 $username, 463 $password, 464); // object(Pdo\Sqlite) 465 466$connection->createFunction( 467 'prepend_php', 468 static fn ($string) => "PHP {$string}", 469); // Does not exist on a mismatching driver. 470 471$connection->query('SELECT prepend_php(version) FROM php'); 472PHP 473 ); ?> 474 </div> 475 </div> 476 </div> 477 <div class="php8-compare__content"> 478 <?= message('pdo_driver_specific_subclasses_description', $lang) ?> 479 </div> 480 </div> 481 <div class="php8-compare"> 482 <h2 class="php8-h2" id="new_without_parentheses"> 483 <?= message('new_without_parentheses_title', $lang) ?> 484 <a class="php8-rfc" href="https://wiki.php.net/rfc/new_without_parentheses">RFC</a> 485 <a class="php8-rfc" href="/manual/<?= $documentation ?>/migration84.new-features.php#migration84.new-features.core.new-chaining"><?= message('documentation', $lang) ?></a> 486 </h2> 487 <div class="php8-compare__main"> 488 <div class="php8-compare__block example-contents"> 489 <div class="php8-compare__label">PHP < 8.4</div> 490 <div class="php8-code phpcode"> 491 <?php highlight_php_trimmed( 492 <<<'PHP' 493class PhpVersion 494{ 495 public function getVersion(): string 496 { 497 return 'PHP 8.3'; 498 } 499} 500 501var_dump((new PhpVersion())->getVersion()); 502PHP 503 504 ); ?> 505 </div> 506 </div> 507 <div class="php8-compare__arrow"></div> 508 <div class="php8-compare__block example-contents"> 509 <div class="php8-compare__label php8-compare__label_new">PHP 8.4</div> 510 <div class="php8-code phpcode"> 511 <?php highlight_php_trimmed( 512 <<<'PHP' 513class PhpVersion 514{ 515 public function getVersion(): string 516 { 517 return 'PHP 8.4'; 518 } 519} 520 521var_dump(new PhpVersion()->getVersion()); 522PHP 523 ); ?> 524 </div> 525 </div> 526 </div> 527 <div class="php8-compare__content"> 528 <?= message('new_without_parentheses_description', $lang) ?> 529 </div> 530 </div> 531 532 </section> 533 534 <section class="php8-section center php8-section_light php8-columns"> 535 <div class="php8-column"> 536 <h2 class="php8-h2" id="other_new_things"><?= message('new_classes_title', $lang) ?></h2> 537 <div class="php8-compare__content php8-compare__content--block"> 538 <ul> 539 <li><?= message('new_lazy_objects', $lang) ?></li> 540 <li><?= message('new_jit_implementation', $lang) ?></li> 541 <li><?= message('new_core_functions', $lang) ?></li> 542 <li><?= message('new_bcmath_functions', $lang) ?></li> 543 <li><?= message('new_round_modes', $lang) ?></li> 544 <li><?= message('new_date_functions', $lang) ?></li> 545 <li><?= message('new_mb_functions', $lang) ?></li> 546 <li><?= message('new_pcntl_functions', $lang) ?></li> 547 <li><?= message('new_reflection_functions', $lang) ?></li> 548 <li><?= message('new_standard_functions', $lang) ?></li> 549 <li><?= message('new_xml_functions', $lang) ?></li> 550 <li><?= message('new_grapheme_function', $lang) ?></li> 551 </ul> 552 </div> 553 </div> 554 555 <div class="php8-column"> 556 <h2 class="php8-h2" id="deprecations_and_bc_breaks"><?= message('bc_title', $lang) ?></h2> 557 <div class="php8-compare__content"> 558 <ul> 559 <li><?= message('bc_pecl', $lang) ?></li> 560 <li><?= message('bc_nullable_parameter_types', $lang) ?></li> 561 <li><?= message('bc_classname', $lang) ?></li> 562 <li><?= message('bc_zero_raised_to_negative_number', $lang) ?></li> 563 <li><?= message('bc_round', $lang) ?></li> 564 <li><?= message('bc_typed_constants', $lang) ?></li> 565 <li><?= message('bc_gmp', $lang) ?></li> 566 <li><?= message('bc_mysqli_constants', $lang) ?></li> 567 <li><?= message('bc_mysqli_functions', $lang) ?></li> 568 <li><?= message('bc_standard', $lang) ?></li> 569 <li><?= message('bc_core', $lang) ?></li> 570 <li><?= message('bc_warnings', $lang) ?></li> 571 </ul> 572 </div> 573 </div> 574 </section> 575 576 <section class="php8-section php8-section_dark php8-section_footer php8-footer"> 577 <div class="php8-section__content"> 578 <h2 class="php8-h2 center"><?= message('footer_title', $lang) ?></h2> 579 <div class="php8-button-wrapper center"> 580 <a class="php8-button php8-button_light" href="/downloads"><?= message('upgrade_now', $lang) ?></a> 581 </div> 582 <div class="php8-footer__content"><?= message('footer_description', $lang) ?></div> 583 </div> 584 </section> 585 586<?php 587 588site_footer(); 589