xref: /web-php/releases/8.4/release.inc (revision 71c7b315)
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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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