xref: /web-php/releases/8.0/zh.php (revision d6a01448)
1<?php
2$_SERVER['BASE_PAGE'] = 'releases/8.0/zh.php';
3include_once __DIR__ . '/common.php';
4
5releases\php80\common_header(
6    'PHP 8.0 是 PHP 语言的一次重大更新。它包含了很多新功能与优化项,' .
7    '包括命名参数、联合类型、注解、构造器属性提升、match 表达式、' .
8    'Nullsafe 运算符、JIT,并改进了类型系统、错误处理、语法一致性。');
9
10?>
11<section class="php8-section php8-section_dark php8-section_header center">
12  <div class="page-tools">
13    <div class="change-language">
14        <?php releases\php80\language_chooser('zh'); ?>
15    </div>
16  </div>
17  <div class="php8-section__content">
18    <div class="php8-logo">
19      <img src="/images/php8/logo_php8.svg" alt="php8" height="126" width="343">
20    </div>
21    <div class="php8-title">已发布!</div>
22    <div class="php8-subtitle">
23      PHP 8.0 是 PHP 语言的一次重大更新。
24      <br class="display-none-md"> 它包含了很多新功能与优化项,
25      包括命名参数、联合类型、注解、构造器属性提升、match 表达式、nullsafe 运算符、JIT,并改进了类型系统、错误处理、语法一致性。
26    </div>
27    <div class="php8-button-wrapper center">
28      <a class="php8-button php8-button_light" href="/downloads">更新到 PHP 8!</a>
29    </div>
30  </div>
31</section>
32
33<section class="php8-section center">
34  <div class="php8-compare">
35    <h2 class="php8-h2" id="named-arguments">
36      命名参数
37      <a class="php8-rfc" href="https://wiki.php.net/rfc/named_params">RFC</a>
38    </h2>
39    <div class="php8-compare__main">
40      <div class="php8-compare__block example-contents">
41        <div class="php8-compare__label">PHP 7</div>
42        <div class="php8-code phpcode">
43            <?php highlight_php_trimmed(
44                'htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, \'UTF-8\', false);',
45            );?>
46        </div>
47
48
49      </div>
50      <div class="php8-compare__arrow"></div>
51      <div class="php8-compare__block example-contents">
52        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
53        <div class="php8-code phpcode">
54            <?php highlight_php_trimmed(
55                'htmlspecialchars($string, double_encode: false);',
56            );?>
57        </div>
58      </div>
59    </div>
60    <div class="php8-compare__content">
61      <ul>
62        <li>仅仅指定必填参数,跳过可选参数。</li>
63        <li>参数的顺序无关、自己就是文档(self-documented)</li>
64      </ul>
65    </div>
66  </div>
67
68  <div class="php8-compare">
69    <h2 class="php8-h2" id="attributes">
70      注解
71      <a class="php8-rfc" href="https://wiki.php.net/rfc/attributes_v2">RFC</a> <a class="php8-rfc" href="/manual/zh/language.attributes.php">Doc</a>
72    </h2>
73    <div class="php8-compare__main">
74      <div class="php8-compare__block example-contents">
75        <div class="php8-compare__label">PHP 7</div>
76        <div class="php8-code phpcode">
77            <?php highlight_php_trimmed(
78                'class PostsController
79{
80    /**
81     * @Route("/api/posts/{id}", methods={"GET"})
82     */
83    public function get($id) { /* ... */ }
84}',
85            );?>
86        </div>
87      </div>
88      <div class="php8-compare__arrow"></div>
89      <div class="php8-compare__block example-contents">
90        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
91        <div class="php8-code phpcode">
92            <?php highlight_php_trimmed(
93                'class PostsController
94{
95    #[Route("/api/posts/{id}", methods: ["GET"])]
96    public function get($id) { /* ... */ }
97}',
98            );?>
99        </div>
100      </div>
101    </div>
102    <div class="php8-compare__content">
103      <p>现在可以用 PHP 原生语法来使用结构化的元数据,而非 PHPDoc 声明。</p>
104    </div>
105  </div>
106
107  <div class="php8-compare">
108    <h2 class="php8-h2" id="constructor-property-promotion">
109        构造器属性提升
110      <a class="php8-rfc" href="https://wiki.php.net/rfc/constructor_promotion">RFC</a> <a class="php8-rfc" href="/manual/zh/language.oop5.decon.php#language.oop5.decon.constructor.promotion">文档</a>
111    </h2>
112    <div class="php8-compare__main">
113      <div class="php8-compare__block example-contents">
114        <div class="php8-compare__label">PHP 7</div>
115        <div class="php8-code phpcode">
116            <?php highlight_php_trimmed(
117                'class Point {
118  public float $x;
119  public float $y;
120  public float $z;
121  public function __construct(
122    float $x = 0.0,
123    float $y = 0.0,
124    float $z = 0.0
125  ) {
126    $this->x = $x;
127    $this->y = $y;
128    $this->z = $z;
129  }
130}',
131            );?>
132        </div>
133      </div>
134      <div class="php8-compare__arrow"></div>
135      <div class="php8-compare__block example-contents">
136        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
137        <div class="php8-code phpcode">
138            <?php highlight_php_trimmed(
139                'class Point {
140  public function __construct(
141    public float $x = 0.0,
142    public float $y = 0.0,
143    public float $z = 0.0,
144  ) {}
145}',
146            );?>
147        </div>
148      </div>
149    </div>
150    <div class="php8-compare__content">
151      <p>更少的样板代码来定义并初始化属性。</p>
152    </div>
153  </div>
154
155  <div class="php8-compare">
156    <h2 class="php8-h2" id="union-types">
157      联合类型
158      <a class="php8-rfc" href="https://wiki.php.net/rfc/union_types_v2">RFC</a> <a class="php8-rfc" href="/manual/zh/language.types.declarations.php#language.types.declarations.composite.union">文档</a>
159    </h2>
160    <div class="php8-compare__main">
161      <div class="php8-compare__block example-contents">
162        <div class="php8-compare__label">PHP 7</div>
163        <div class="php8-code phpcode">
164            <?php highlight_php_trimmed(
165                'class Number {
166  /** @var int|float */
167  private $number;
168  /**
169   * @param float|int $number
170   */
171  public function __construct($number) {
172    $this->number = $number;
173  }
174}
175new Number(\'NaN\'); // Ok',
176            );?>
177        </div>
178      </div>
179      <div class="php8-compare__arrow"></div>
180      <div class="php8-compare__block example-contents">
181        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
182        <div class="php8-code phpcode">
183            <?php highlight_php_trimmed(
184                'class Number {
185  public function __construct(
186    private int|float $number
187  ) {}
188}
189new Number(\'NaN\'); // TypeError',
190            );?>
191        </div>
192      </div>
193    </div>
194    <div class="php8-compare__content">
195      <p>相较于以前的 PHPDoc 声明类型的组合,
196      现在可以用原生支持的联合类型声明取而代之,并在运行时得到校验。</p>
197    </div>
198  </div>
199
200  <div class="php8-compare">
201    <h2 class="php8-h2" id="match-expression">
202      Match 表达式
203      <a class="php8-rfc" href="https://wiki.php.net/rfc/match_expression_v2">RFC</a> <a class="php8-rfc" href="/manual/zh/control-structures.match.php">文档</a>
204    </h2>
205    <div class="php8-compare__main">
206      <div class="php8-compare__block example-contents">
207        <div class="php8-compare__label">PHP 7</div>
208        <div class="php8-code phpcode">
209            <?php highlight_php_trimmed(
210                'switch (8.0) {
211  case \'8.0\':
212    $result = "Oh no!";
213    break;
214  case 8.0:
215    $result = "This is what I expected";
216    break;
217}
218echo $result;
219//> Oh no!',
220            );?>
221        </div>
222      </div>
223      <div class="php8-compare__arrow"></div>
224      <div class="php8-compare__block example-contents">
225        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
226        <div class="php8-code phpcode">
227            <?php highlight_php_trimmed(
228                'echo match (8.0) {
229  \'8.0\' => "Oh no!",
230  8.0 => "This is what I expected",
231};
232//> This is what I expected',
233            );?>
234        </div>
235      </div>
236    </div>
237    <div class="php8-compare__content">
238      <p>新的 match 类似于 switch,并具有以下功能:</p>
239      <ul>
240        <li>Match 是一个表达式,它可以储存到变量中亦可以直接返回。</li>
241        <li>Match 分支仅支持单行,它不需要一个 break; 语句。</li>
242        <li>Match 使用严格比较。</li>
243      </ul>
244    </div>
245  </div>
246
247  <div class="php8-compare">
248    <h2 class="php8-h2" id="nullsafe-operator">
249      Nullsafe 运算符
250      <a class="php8-rfc" href="https://wiki.php.net/rfc/nullsafe_operator">RFC</a>
251    </h2>
252    <div class="php8-compare__main">
253      <div class="php8-compare__block example-contents">
254        <div class="php8-compare__label">PHP 7</div>
255        <div class="php8-code phpcode">
256            <?php highlight_php_trimmed(
257                '$country =  null;
258if ($session !== null) {
259  $user = $session->user;
260  if ($user !== null) {
261    $address = $user->getAddress();
262
263    if ($address !== null) {
264      $country = $address->country;
265    }
266  }
267}',
268            );?>
269        </div>
270      </div>
271      <div class="php8-compare__arrow"></div>
272      <div class="php8-compare__block example-contents">
273        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
274        <div class="php8-code phpcode">
275            <?php highlight_php_trimmed(
276                '$country = $session?->user?->getAddress()?->country;',
277            );?>
278        </div>
279      </div>
280    </div>
281    <div class="php8-compare__content">
282      <p>现在可以用新的 nullsafe 运算符链式调用,而不需要条件检查 null。
283        如果链条中的一个元素失败了,整个链条会中止并认定为 Null。</p>
284    </div>
285  </div>
286
287  <div class="php8-compare">
288    <h2 class="php8-h2" id="saner-string-to-number-comparisons">
289      字符串与数字的比较更符合逻辑
290      <a class="php8-rfc" href="https://wiki.php.net/rfc/string_to_number_comparison">RFC</a>
291    </h2>
292    <div class="php8-compare__main">
293      <div class="php8-compare__block example-contents">
294        <div class="php8-compare__label">PHP 7</div>
295        <div class="php8-code phpcode">
296            <?php highlight_php_trimmed(
297                '0 == \'foobar\' // true',
298            );?>
299        </div>
300      </div>
301      <div class="php8-compare__arrow"></div>
302      <div class="php8-compare__block example-contents">
303        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
304        <div class="php8-code phpcode">
305            <?php highlight_php_trimmed(
306                '0 == \'foobar\' // false',
307            );?>
308        </div>
309      </div>
310    </div>
311    <div class="php8-compare__content">
312      <p>PHP 8 比较数字字符串(numeric string)时,会按数字进行比较。
313        不是数字字符串时,将数字转化为字符串,按字符串比较。</p>
314    </div>
315  </div>
316
317  <div class="php8-compare">
318    <h2 class="php8-h2" id="consistent-type-errors-for-internal-functions">
319      内部函数类型错误的一致性。
320      <a class="php8-rfc" href="https://wiki.php.net/rfc/consistent_type_errors">RFC</a>
321    </h2>
322    <div class="php8-compare__main">
323      <div class="php8-compare__block example-contents">
324        <div class="php8-compare__label">PHP 7</div>
325        <div class="php8-code phpcode">
326            <?php highlight_php_trimmed(
327                'strlen([]); // Warning: strlen() expects parameter 1 to be string, array given
328array_chunk([], -1); // Warning: array_chunk(): Size parameter expected to be greater than 0',
329            );?>
330        </div>
331      </div>
332      <div class="php8-compare__arrow"></div>
333      <div class="php8-compare__block example-contents">
334        <div class="php8-compare__label php8-compare__label_new">PHP 8</div>
335        <div class="php8-code phpcode">
336            <?php highlight_php_trimmed(
337                'strlen([]); // TypeError: strlen(): Argument #1 ($str) must be of type string, array given
338array_chunk([], -1); // ValueError: array_chunk(): Argument #2 ($length) must be greater than 0',
339            );?>
340        </div>
341      </div>
342    </div>
343    <div class="php8-compare__content">
344      <p>现在大多数内部函数在参数验证失败时抛出 Error 级异常。</p>
345    </div>
346  </div>
347</section>
348
349<section class="php8-section php8-section_light">
350  <h2 class="php8-h2">即时编译</h2>
351  <p>
352    PHP 8 引入了两个即时编译引擎。
353    Tracing JIT 在两个中更有潜力,它在综合基准测试中显示了三倍的性能,
354    并在某些长时间运行的程序中显示了 1.5-2 倍的性能改进。
355    典型的应用性能则和 PHP 7.4 不相上下。
356  </p>
357  <h3 class="php8-h3">
358    关于 JIT 对 PHP 8 性能的贡献
359  </h3>
360  <p>
361    <img src="/images/php8/scheme.svg" width="900" alt="Just-In-Time compilation">
362  </p>
363
364  <div class="php8-columns">
365    <div class="php8-column">
366      <h2 class="php8-h2 php8-h2_margin-top">类型系统与错误处理的改进</h2>
367      <ul>
368        <li>
369          算术/位运算符更严格的类型检测
370          <a href="https://wiki.php.net/rfc/arithmetic_operator_type_checks">RFC</a>
371        </li>
372        <li>
373          Abstract trait 方法的验证 <a href="https://wiki.php.net/rfc/abstract_trait_method_validation">RFC</a>
374        </li>
375        <li>
376          确保魔术方法签名正确 <a href="https://wiki.php.net/rfc/magic-methods-signature">RFC</a>
377        </li>
378        <li>
379          PHP 引擎 warning 警告的重新分类 <a href="https://wiki.php.net/rfc/engine_warnings">RFC</a>
380        </li>
381        <li>
382          不兼容的方法签名导致 Fatal 错误 <a href="https://wiki.php.net/rfc/lsp_errors">RFC</a>
383        </li>
384        <li>
385          操作符 @ 不再抑制 fatal 错误。
386        </li>
387        <li>
388          私有方法继承 <a href="https://wiki.php.net/rfc/inheritance_private_methods">RFC</a>
389        </li>
390        <li>
391          Mixed 类型 <a href="https://wiki.php.net/rfc/mixed_type_v2">RFC</a>
392        </li>
393        <li>
394          Static 返回类型 <a href="https://wiki.php.net/rfc/static_return_type">RFC</a>
395        </li>
396        <li>
397        内部函数的类型
398          <a href="https://externals.io/message/106522">Email thread</a>
399        </li>
400        <li>
401          扩展
402            <a href="https://php.watch/versions/8.0/resource-CurlHandle">Curl</a>、
403            <a href="https://php.watch/versions/8.0/gdimage">Gd</a>、
404            <a href="https://php.watch/versions/8.0/sockets-sockets-addressinfo">Sockets</a>、
405            <a href="https://php.watch/versions/8.0/OpenSSL-resource">OpenSSL</a>、
406            <a href="https://php.watch/versions/8.0/xmlwriter-resource">XMLWriter</a>、
407            <a href="https://php.watch/versions/8.0/xmlwriter-resource">XML</a>
408            以 Opaque 对象替换 resource。
409        </li>
410      </ul>
411    </div>
412    <div class="php8-column">
413      <h2 class="php8-h2 php8-h2_margin-top">其他语法调整和改进</h2>
414      <ul>
415        <li>
416          允许参数列表中的末尾逗号 <a href="https://wiki.php.net/rfc/trailing_comma_in_parameter_list">RFC</a>、
417          闭包 use 列表中的末尾逗号 <a href="https://wiki.php.net/rfc/trailing_comma_in_closure_use_list">RFC</a>
418        </li>
419        <li>
420          无变量捕获的 catch <a href="https://wiki.php.net/rfc/non-capturing_catches">RFC</a>
421        </li>
422        <li>
423          变量语法的调整 <a href="https://wiki.php.net/rfc/variable_syntax_tweaks">RFC</a>
424        </li>
425        <li>
426           Namespace 名称作为单个 token <a href="https://wiki.php.net/rfc/namespaced_names_as_token">RFC</a>
427        </li>
428        <li>
429          现在 throw 是一个表达式 <a href="https://wiki.php.net/rfc/throw_expression">RFC</a>
430        </li>
431        <li>
432          允许对象的 ::class <a href="https://wiki.php.net/rfc/class_name_literal_on_object">RFC</a>
433        </li>
434      </ul>
435
436      <h2 class="php8-h2 php8-h2_margin-top">新的类、接口、函数</h2>
437      <ul>
438        <li>
439          <a href="https://wiki.php.net/rfc/weak_maps">Weak Map</a> 类
440        </li>
441        <li>
442          <a href="https://wiki.php.net/rfc/stringable">Stringable</a> 接口
443        </li>
444        <li>
445          <a href="https://wiki.php.net/rfc/str_contains">str_contains()</a>、
446          <a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions">str_starts_with()</a>、
447          <a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions">str_ends_with()</a>
448        </li>
449        <li>
450          <a href="https://github.com/php/php-src/pull/4769">fdiv()</a>
451        </li>
452        <li>
453          <a href="https://wiki.php.net/rfc/get_debug_type">get_debug_type()</a>
454        </li>
455        <li>
456          <a href="https://github.com/php/php-src/pull/5427">get_resource_id()</a>
457        </li>
458        <li>
459          <a href="https://wiki.php.net/rfc/token_as_object">token_get_all()</a> 对象实现
460        </li>
461        <li>
462          <a href="https://wiki.php.net/rfc/dom_living_standard_api">New DOM Traversal and Manipulation APIs</a>
463        </li>
464      </ul>
465    </div>
466  </div>
467</section>
468
469<section class="php8-section php8-section_dark php8-section_footer php8-footer">
470  <div class="php8-section__content">
471    <h2 class="php8-h2 center">
472      性能更好,语法更好,类型安全更完善
473    </h2>
474    <div class="php8-button-wrapper center">
475      <a class="php8-button php8-button_light" href="/downloads">更新到 PHP 8!</a>
476    </div>
477    <div class="php8-footer__content">
478      <p>
479        请访问 <a href="http://www.php.net/downloads">下载</a> 页面下载 PHP 8 源代码。
480        在 <a href="http://windows.php.net/download">PHP for Windows</a> 站点中可找到 Windows 二进制文件。
481        <a href="http://www.php.net/ChangeLog-8.php">ChangeLog</a> 中有变更历史记录清单。
482      </p>
483      <p>
484        PHP 手册中有 <a href="/manual/zh/migration80.php">迁移指南</a>。
485        请参考它描述的新功能详细清单、向后不兼容的变化。
486      </p>
487    </div>
488  </div>
489</section>
490
491
492
493
494<?php site_footer();
495