xref: /web-php/releases/8.0/en.php (revision c093fb53)
1<?php
2$_SERVER['BASE_PAGE'] = 'releases/8.0/en.php';
3include_once __DIR__ . '/common.php';
4
5releases\php80\common_header(
6    'PHP 8.0 is a major update of the PHP language. ' .
7    'It contains many new features and optimizations including ' .
8    'named arguments, union types, attributes, constructor property promotion, ' .
9    'match expression, nullsafe operator, JIT, and ' .
10    'improvements in the type system, error handling, and consistency.');
11
12?>
13<section class="php8-section php8-section_dark php8-section_header center">
14  <div class="page-tools">
15    <div class="change-language">
16        <?php releases\php80\language_chooser('en'); ?>
17    </div>
18  </div>
19  <div class="php8-section__content">
20    <div class="php8-logo">
21      <img src="/images/php8/logo_php8.svg" alt="php8" height="126" width="343">
22    </div>
23    <div class="php8-title">Released!</div>
24    <div class="php8-subtitle">
25      PHP 8.0 is a major update of the PHP language.<br class="display-none-md"> It contains many new features and
26      optimizations including named arguments, union types, attributes, constructor property promotion, match
27      expression, nullsafe operator, JIT, and improvements in the type system, error handling, and consistency.
28    </div>
29    <div class="php8-button-wrapper center">
30      <a class="php8-button php8-button_light" href="/downloads">Upgrade to PHP 8 now!</a>
31    </div>
32  </div>
33</section>
34
35<section class="php8-section center">
36  <div class="php8-compare">
37    <h2 class="php8-h2" id="named-arguments">
38      Named arguments
39      <a class="php8-rfc" href="https://wiki.php.net/rfc/named_params">RFC</a>
40    </h2>
41    <div class="php8-compare__main">
42      <div class="php8-compare__block example-contents">
43        <div class="php8-compare__label">PHP 7</div>
44        <div class="php8-code phpcode">
45            <?php highlight_php_trimmed(
46                'htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, \'UTF-8\', false);',
47            );?>
48        </div>
49
50
51      </div>
52      <div class="php8-compare__arrow"></div>
53      <div class="php8-compare__block example-contents">
54        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
55        <div class="php8-code phpcode">
56            <?php highlight_php_trimmed(
57                'htmlspecialchars($string, double_encode: false);',
58            );?>
59        </div>
60      </div>
61    </div>
62    <div class="php8-compare__content">
63      <ul>
64        <li>Specify only required parameters, skipping optional ones.</li>
65        <li>Arguments are order-independent and self-documented.</li>
66      </ul>
67    </div>
68  </div>
69
70  <div class="php8-compare">
71    <h2 class="php8-h2" id="attributes">
72      Attributes
73      <a class="php8-rfc" href="https://wiki.php.net/rfc/attributes_v2">RFC</a> <a class="php8-rfc" href="/manual/en/language.attributes.php">Doc</a>
74    </h2>
75    <div class="php8-compare__main">
76      <div class="php8-compare__block example-contents">
77        <div class="php8-compare__label">PHP 7</div>
78        <div class="php8-code phpcode">
79            <?php highlight_php_trimmed(
80                'class PostsController
81{
82    /**
83     * @Route("/api/posts/{id}", methods={"GET"})
84     */
85    public function get($id) { /* ... */ }
86}',
87            );?>
88        </div>
89      </div>
90      <div class="php8-compare__arrow"></div>
91      <div class="php8-compare__block example-contents">
92        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
93        <div class="php8-code phpcode">
94            <?php highlight_php_trimmed(
95                'class PostsController
96{
97    #[Route("/api/posts/{id}", methods: ["GET"])]
98    public function get($id) { /* ... */ }
99}',
100            );?>
101        </div>
102      </div>
103    </div>
104    <div class="php8-compare__content">
105      <p>Instead of PHPDoc annotations, you can now use structured metadata with PHP's native syntax.</p>
106    </div>
107  </div>
108
109  <div class="php8-compare">
110    <h2 class="php8-h2" id="constructor-property-promotion">
111      Constructor property promotion
112      <a class="php8-rfc" href="https://wiki.php.net/rfc/constructor_promotion">RFC</a> <a class="php8-rfc" href="/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion">Doc</a>
113    </h2>
114    <div class="php8-compare__main">
115      <div class="php8-compare__block example-contents">
116        <div class="php8-compare__label">PHP 7</div>
117        <div class="php8-code phpcode">
118            <?php highlight_php_trimmed(
119                'class Point {
120  public float $x;
121  public float $y;
122  public float $z;
123
124  public function __construct(
125    float $x = 0.0,
126    float $y = 0.0,
127    float $z = 0.0
128  ) {
129    $this->x = $x;
130    $this->y = $y;
131    $this->z = $z;
132  }
133}',
134            );?>
135        </div>
136      </div>
137      <div class="php8-compare__arrow"></div>
138      <div class="php8-compare__block example-contents">
139        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
140        <div class="php8-code phpcode">
141            <?php highlight_php_trimmed(
142                'class Point {
143  public function __construct(
144    public float $x = 0.0,
145    public float $y = 0.0,
146    public float $z = 0.0,
147  ) {}
148}',
149            );?>
150        </div>
151      </div>
152    </div>
153    <div class="php8-compare__content">
154      <p>Less boilerplate code to define and initialize properties.</p>
155    </div>
156  </div>
157
158  <div class="php8-compare">
159    <h2 class="php8-h2" id="union-types">
160      Union types
161      <a class="php8-rfc" href="https://wiki.php.net/rfc/union_types_v2">RFC</a> <a class="php8-rfc" href="/manual/en/language.types.declarations.php#language.types.declarations.union">Doc</a>
162    </h2>
163    <div class="php8-compare__main">
164      <div class="php8-compare__block example-contents">
165        <div class="php8-compare__label">PHP 7</div>
166        <div class="php8-code phpcode">
167            <?php highlight_php_trimmed(
168                'class Number {
169  /** @var int|float */
170  private $number;
171
172  /**
173   * @param float|int $number
174   */
175  public function __construct($number) {
176    $this->number = $number;
177  }
178}
179
180new Number(\'NaN\'); // Ok',
181            );?>
182        </div>
183      </div>
184      <div class="php8-compare__arrow"></div>
185      <div class="php8-compare__block example-contents">
186        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
187        <div class="php8-code phpcode">
188            <?php highlight_php_trimmed(
189                'class Number {
190  public function __construct(
191    private int|float $number
192  ) {}
193}
194
195new Number(\'NaN\'); // TypeError',
196            );?>
197        </div>
198      </div>
199    </div>
200    <div class="php8-compare__content">
201      <p>Instead of PHPDoc annotations for a combination of types, you can use native union type declarations that are
202        validated at runtime.</p>
203    </div>
204  </div>
205
206  <div class="php8-compare">
207    <h2 class="php8-h2" id="match-expression">
208      Match expression
209      <a class="php8-rfc" href="https://wiki.php.net/rfc/match_expression_v2">RFC</a> <a class="php8-rfc" href="/manual/en/control-structures.match.php">Doc</a>
210    </h2>
211    <div class="php8-compare__main">
212      <div class="php8-compare__block example-contents">
213        <div class="php8-compare__label">PHP 7</div>
214        <div class="php8-code phpcode">
215            <?php highlight_php_trimmed(
216                'switch (8.0) {
217  case \'8.0\':
218    $result = "Oh no!";
219    break;
220  case 8.0:
221    $result = "This is what I expected";
222    break;
223}
224echo $result;
225//> Oh no!',
226            );?>
227        </div>
228      </div>
229      <div class="php8-compare__arrow"></div>
230      <div class="php8-compare__block example-contents">
231        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
232        <div class="php8-code phpcode">
233            <?php highlight_php_trimmed(
234                'echo match (8.0) {
235  \'8.0\' => "Oh no!",
236  8.0 => "This is what I expected",
237};
238//> This is what I expected',
239            );?>
240        </div>
241      </div>
242    </div>
243    <div class="php8-compare__content">
244      <p>The new match is similar to switch and has the following features:</p>
245      <ul>
246        <li>Match is an expression, meaning its result can be stored in a variable or returned.</li>
247        <li>Match branches only support single-line expressions and do not need a break; statement.</li>
248        <li>Match does strict comparisons.</li>
249      </ul>
250    </div>
251  </div>
252
253  <div class="php8-compare">
254    <h2 class="php8-h2" id="nullsafe-operator">
255      Nullsafe operator
256      <a class="php8-rfc" href="https://wiki.php.net/rfc/nullsafe_operator">RFC</a>
257    </h2>
258    <div class="php8-compare__main">
259      <div class="php8-compare__block example-contents">
260        <div class="php8-compare__label">PHP 7</div>
261        <div class="php8-code phpcode">
262            <?php highlight_php_trimmed(
263                '$country =  null;
264
265if ($session !== null) {
266  $user = $session->user;
267
268  if ($user !== null) {
269    $address = $user->getAddress();
270
271    if ($address !== null) {
272      $country = $address->country;
273    }
274  }
275}',
276            );?>
277        </div>
278      </div>
279      <div class="php8-compare__arrow"></div>
280      <div class="php8-compare__block example-contents">
281        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
282        <div class="php8-code phpcode">
283            <?php highlight_php_trimmed(
284                '$country = $session?->user?->getAddress()?->country;',
285            );?>
286        </div>
287      </div>
288    </div>
289    <div class="php8-compare__content">
290      <p>Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the
291        evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain
292        evaluates to null.</p>
293    </div>
294  </div>
295
296  <div class="php8-compare">
297    <h2 class="php8-h2" id="saner-string-to-number-comparisons">
298      Saner string to number comparisons
299      <a class="php8-rfc" href="https://wiki.php.net/rfc/string_to_number_comparison">RFC</a>
300    </h2>
301    <div class="php8-compare__main">
302      <div class="php8-compare__block example-contents">
303        <div class="php8-compare__label">PHP 7</div>
304        <div class="php8-code phpcode">
305            <?php highlight_php_trimmed(
306                '0 == \'foobar\' // true',
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</div>
313        <div class="php8-code phpcode">
314            <?php highlight_php_trimmed(
315                '0 == \'foobar\' // false',
316            );?>
317        </div>
318      </div>
319    </div>
320    <div class="php8-compare__content">
321      <p>When comparing to a numeric string, PHP 8 uses a number comparison. Otherwise, it converts the number to a
322        string and uses a string comparison.</p>
323    </div>
324  </div>
325
326  <div class="php8-compare">
327    <h2 class="php8-h2" id="consistent-type-errors-for-internal-functions">
328      Consistent type errors for internal functions
329      <a class="php8-rfc" href="https://wiki.php.net/rfc/consistent_type_errors">RFC</a>
330    </h2>
331    <div class="php8-compare__main">
332      <div class="php8-compare__block example-contents">
333        <div class="php8-compare__label">PHP 7</div>
334        <div class="php8-code phpcode">
335            <?php highlight_php_trimmed(
336                'strlen([]); // Warning: strlen() expects parameter 1 to be string, array given
337
338array_chunk([], -1); // Warning: array_chunk(): Size parameter expected to be greater than 0',
339            );?>
340        </div>
341      </div>
342      <div class="php8-compare__arrow"></div>
343      <div class="php8-compare__block example-contents">
344        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
345        <div class="php8-code phpcode">
346            <?php highlight_php_trimmed(
347                'strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given
348
349array_chunk([], -1); // ValueError: array_chunk(): Argument #2 ($length) must be greater than 0',
350            );?>
351        </div>
352      </div>
353    </div>
354    <div class="php8-compare__content">
355      <p>Most of the internal functions now throw an Error exception if the validation of the parameters fails.</p>
356    </div>
357  </div>
358</section>
359
360<section class="php8-section php8-section_light">
361  <h2 class="php8-h2">Just-In-Time compilation</h2>
362  <p>
363    PHP 8 introduces two JIT compilation engines. Tracing JIT, the most promising of the two, shows about 3 times better
364    performance on synthetic benchmarks and 1.5–2 times improvement on some specific long-running applications. Typical
365    application performance is on par with PHP 7.4.
366  </p>
367  <h3 class="php8-h3">
368    Relative JIT contribution to PHP 8 performance
369  </h3>
370  <p>
371    <img src="/images/php8/scheme.svg" width="900" alt="Just-In-Time compilation">
372  </p>
373
374  <div class="php8-columns">
375    <div class="php8-column">
376      <h2 class="php8-h2 php8-h2_margin-top">Type system and error handling improvements</h2>
377      <ul>
378        <li>
379          Stricter type checks for arithmetic/bitwise operators
380          <a href="https://wiki.php.net/rfc/arithmetic_operator_type_checks">RFC</a>
381        </li>
382        <li>
383          Abstract trait method validation <a href="https://wiki.php.net/rfc/abstract_trait_method_validation">RFC</a>
384        </li>
385        <li>
386          Correct signatures of magic methods <a href="https://wiki.php.net/rfc/magic-methods-signature">RFC</a>
387        </li>
388        <li>
389          Reclassified engine warnings <a href="https://wiki.php.net/rfc/engine_warnings">RFC</a>
390        </li>
391        <li>
392          Fatal error for incompatible method signatures <a href="https://wiki.php.net/rfc/lsp_errors">RFC</a>
393        </li>
394        <li>
395          The @ operator no longer silences fatal errors.
396        </li>
397        <li>
398          Inheritance with private methods <a href="https://wiki.php.net/rfc/inheritance_private_methods">RFC</a>
399        </li>
400        <li>
401          Mixed type <a href="https://wiki.php.net/rfc/mixed_type_v2">RFC</a>
402        </li>
403        <li>
404          Static return type <a href="https://wiki.php.net/rfc/static_return_type">RFC</a>
405        </li>
406        <li>
407          Types for internal functions
408          <a href="https://externals.io/message/106522">Email thread</a>
409        </li>
410        <li>
411          Opaque objects instead of resources for
412            <a href="https://php.watch/versions/8.0/resource-CurlHandle">Curl</a>,
413            <a href="https://php.watch/versions/8.0/gdimage">Gd</a>,
414            <a href="https://php.watch/versions/8.0/sockets-sockets-addressinfo">Sockets</a>,
415            <a href="https://php.watch/versions/8.0/OpenSSL-resource">OpenSSL</a>,
416            <a href="https://php.watch/versions/8.0/xmlwriter-resource">XMLWriter</a>, and
417            <a href="https://php.watch/versions/8.0/xmlwriter-resource">XML</a>
418            extensions
419        </li>
420      </ul>
421    </div>
422    <div class="php8-column">
423      <h2 class="php8-h2 php8-h2_margin-top">Other syntax tweaks and improvements</h2>
424      <ul>
425        <li>
426          Allow a trailing comma in parameter lists <a href="https://wiki.php.net/rfc/trailing_comma_in_parameter_list">RFC</a>
427          and closure use lists <a href="https://wiki.php.net/rfc/trailing_comma_in_closure_use_list">RFC</a>
428        </li>
429        <li>
430          Non-capturing catches <a href="https://wiki.php.net/rfc/non-capturing_catches">RFC</a>
431        </li>
432        <li>
433          Variable Syntax Tweaks <a href="https://wiki.php.net/rfc/variable_syntax_tweaks">RFC</a>
434        </li>
435        <li>
436          Treat namespaced names as single token <a href="https://wiki.php.net/rfc/namespaced_names_as_token">RFC</a>
437        </li>
438        <li>
439          Throw is now an expression <a href="https://wiki.php.net/rfc/throw_expression">RFC</a>
440        </li>
441        <li>
442          Allow ::class on objects <a href="https://wiki.php.net/rfc/class_name_literal_on_object">RFC</a>
443        </li>
444      </ul>
445
446      <h2 class="php8-h2 php8-h2_margin-top">New Classes, Interfaces, and Functions</h2>
447      <ul>
448        <li>
449          <a href="https://wiki.php.net/rfc/weak_maps">Weak Map</a> class
450        </li>
451        <li>
452          <a href="https://wiki.php.net/rfc/stringable">Stringable</a> interface
453        </li>
454        <li>
455          <a href="https://wiki.php.net/rfc/str_contains">str_contains()</a>,
456          <a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions">str_starts_with()</a>,
457          <a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions">str_ends_with()</a>
458        </li>
459        <li>
460          <a href="https://github.com/php/php-src/pull/4769">fdiv()</a>
461        </li>
462        <li>
463          <a href="https://wiki.php.net/rfc/get_debug_type">get_debug_type()</a>
464        </li>
465        <li>
466          <a href="https://github.com/php/php-src/pull/5427">get_resource_id()</a>
467        </li>
468        <li>
469          <a href="https://wiki.php.net/rfc/token_as_object">token_get_all()</a> object implementation
470        </li>
471        <li>
472          <a href="https://wiki.php.net/rfc/dom_living_standard_api">New DOM Traversal and Manipulation APIs</a>
473        </li>
474      </ul>
475    </div>
476  </div>
477</section>
478
479<section class="php8-section php8-section_dark php8-section_footer php8-footer">
480  <div class="php8-section__content">
481    <h2 class="php8-h2 center">
482      Better performance, better syntax, improved type safety.
483    </h2>
484    <div class="php8-button-wrapper center">
485      <a class="php8-button php8-button_light" href="/downloads">Upgrade to PHP 8 now!</a>
486    </div>
487    <div class="php8-footer__content">
488      <p>
489        For source downloads of PHP 8 please visit the <a href="http://www.php.net/downloads">downloads</a> page.
490        Windows binaries can be found on the <a href="http://windows.php.net/download">PHP for Windows</a> site.
491        The list of changes is recorded in the <a href="http://www.php.net/ChangeLog-8.php">ChangeLog</a>.
492      </p>
493      <p>
494        The <a href="/manual/en/migration80.php">migration guide</a> is available in the PHP Manual. Please
495        consult it for a detailed list of new features and backward-incompatible changes.
496      </p>
497    </div>
498  </div>
499</section>
500
501
502
503
504<?php site_footer();
505