重新修订
此投稿已在 4年前 合并。
标题修改:
标签修改:
内容修改:
| Old | New | Differences |
|---|---|---|
| 44 | 44 | |
| 45 | 45 | ### Fibers RFC |
| 46 | 46 | |
| 47 | Fibers — | |
| 47 | Fibers —— 又叫 ["绿色线程"](https://en.wikipedia.org/wiki/Green_threads) — 是管理并行性的低级机制。您可能不会直接在您的应用程序中使用它,但像 Amphp 和 ReactPHP 等框架将大量使用它们。 | |
| 48 | 48 | |
| 49 | 49 | 这里有一个使用 fibers 的简单例子: |
| 50 | 50 | … | … |
| 60 | 60 | $fiber->resume('after resuming'); |
| 61 | 61 | ``` |
| 62 | 62 | |
| 63 | 如果您想读取更多关于 fibers 的信息, 它们能做什么,不能做什么, 你可以阅读 [这篇文章](https://stitcher.io/blog/fibers-with-a-grain-of-salt). | |
| 64 | ||
| 65 | * * * * * | |
| 66 | ||
| 63 | 如果您想读取更多关于 fibers 的信息,它们能做什么,不能做什么,你可以阅读 [这篇文章](https://stitcher.io/blog/fibers-with-a-grain-of-salt)。 | |
| 64 | ||
| 65 | * * * * * | |
| 67 | 66 | |
| 68 | 67 | |
| 69 | 68 | ### 性能提升 PR |
| 70 | 69 | |
| 71 | 70 | |
| 72 | Dmitry Stogov 对 opcache 进行了一些改进,他称之为 「[ | |
| 71 | Dmitry Stogov 对 opcache 进行了一些改进,他称之为 「[继承缓存(inheritance cache)](https://github.com/php/php-src/pull/6627)」。这个新特性允许在缓存中连接两个类,就像 PHP 7.4 中两个类的 [预加载](https://stitcher.io/blog/preloading-in-php-74) 一样。 | |
| 73 | 72 | |
| 74 | 73 | 得益于这个新特性,Dmitry 说会提升 5% 到 8% 的性能,这是 PHP 8.1 中一个很好的小细节。 |
| 75 | 74 | … | … |
| 77 | 76 | |
| 78 | 77 | ### 关联数组解包 RFC |
| 79 | 78 | |
| 80 | 数组的解包操作已经在 [PHP 7.4](https://stitcher.io/blog/new-in-php-74) 中支持了,但是只在数值数组中好用。之前不支持关联数组解包的原因是 | |
| 79 | 数组的解包操作已经在 [PHP 7.4](https://stitcher.io/blog/new-in-php-74) 中支持了,但是只在数值数组中好用。之前不支持关联数组解包的原因是因为在合并重复的数组键的问题上未能达成统一。RFC 使用类似于 `array_merge` 的规则解决了这个问题。 | |
| 81 | 80 | |
| 82 | 81 | ``` |
| 83 | 82 | $array1 = ["a" => 1]; | … | … |
| 93 | 92 | |
| 94 | 93 | |
| 95 | 94 | |
| 96 | ### | |
| 97 |
| |
| 98 | 此 | |
| 95 | ### 使用 `new` 进行初始化设定 RFC | |
| 96 | ||
| 97 | 此 RFC 允许您在函数定义中使用关键字 `new` 作为默认参数,也可以在属性参数等地方使用。 | |
| 99 | 98 | |
| 100 | 99 | ``` |
| 101 | 100 | class MyController { | … | … |
| 105 | 104 | } |
| 106 | 105 | ``` |
| 107 | 106 | |
| 108 | 您可以在 | |
| 109 |
| |
| 110 | * * * * *
| |
| 111 |
| |
| 112 | ### 只读 | |
| 107 | 您可以在 [这篇专题文章](https://stitcher.io/blog/php-81-new-in-initializers) 中阅读关于此功能的所有内容。 | |
| 108 | ||
| 109 | * * * * * | |
| 110 | ||
| 111 | ### 只读属性 RFC | |
| 113 | 112 | |
| 114 | 113 | 类属性可以标记为只读,这意味着它们只能写入一次。 |
| 115 | 114 | … | … |
| 132 | 131 | Error: Cannot modify readonly property Post::$title |
| 133 | 132 | ``` |
| 134 | 133 | |
| 135 | 如果您想深入了解有关只读属性的更多信息,可以阅读 [我的后续文章](https://stitcher.io/blog/php-81-readonly-properties). | |
| 136 | ||
| 137 | * * * * * | |
| 138 | ||
| 139 | ||
| 140 | ||
| 141 | 你想了解更多关于PHP 8.1吗?有 [PHP 8.1之路](https://road-to-php.com/)。在接下来的十天里,你每天会收到邮件覆盖新的PHP 8.1和退出功能;之后你会自动unsubscribed 所以没有垃圾邮件或跟踪。[现在就订阅!](https://road-to-php.com/) | |
| 142 | ||
| 143 | ### 一流的可调用语法RFC | |
| 144 | ||
| 145 | 现在,您可以通过调用一个可调用对象并将其作为参数传递 `…`,从该可调用对象生成闭包: | |
| 134 | 如果您想深入了解有关只读属性的更多信息,可以阅读 [我的后续文章](https://stitcher.io/blog/php-81-readonly-properties)。 | |
| 135 | ||
| 136 | * * * * * | |
| 137 | ||
| 138 | >你想了解更多关于 PHP 8.1 吗?可以看一下 [PHP 8.1之路](https://road-to-php.com/)。在接下来的十天里,你每天会收到一封邮件,邮件中包含 PHP 8.1 的新功能和现有功能;在那之后会为你自动退订,因此不用担心垃圾邮件的问题。[现在就订阅!](https://road-to-php.com/) | |
| 139 | ||
| 140 | ### 最好的可调用语法 RFC | |
| 141 | ||
| 142 | 你现在可以通过调用一个方法,并向它传递 `...`,从而创建一个闭包。 | |
| 146 | 143 | |
| 147 | 144 | ``` |
| 148 | 145 | function foo(int $a, int $b) { /* … */ } | … | … |
| 150 | 147 | $foo = foo(...); |
| 151 | 148 | |
| 152 | 149 | $foo(a: 1, b: 2); |
| 150 | ||
| 153 | 151 | ``` |
| 154 | 152 | |
| 155 | 153 | * * * * * |
| 156 | 154 | |
| 157 | 155 | ### RFC 中的纯交叉类型 |
| 158 | 156 | |
| 159 | 您已经了解了[PHP 8.0中的 | |
| 157 | 您已经了解了[PHP 8.0中的联合类型](https://stitcher.io/blog/new-in-php-8#union-types-rfc),交叉类型是一个类似的功能。如果联合类型的要求是输入的类型在给定类型中,那么交叉类型的要求就是输入的类型为所有指定类型。交叉类型在处理大量接口时特别有用: | |
| 160 | 158 | |
| 161 | 159 | ``` |
| 162 | 160 | function generateSlug(HasTitle&HasId $post) { | … | … |
| 172 | 170 | |
| 173 | 171 | ### 新类型 `never` RFC |
| 174 | 172 | |
| 175 | ||
| 176 | ||
| 177 | 173 | `never` 类型可以用来表示整个程序在一个函数中终止了。可以通过抛出异常、调用`exit`、或是其他类似的函数来实现。 |
| 178 | 174 | |
| 179 | 175 | ``` | … | … |
| 191 | 187 | |
| 192 | 188 | ### 新函数 `array_is_list` RFC |
| 193 | 189 | |
| 194 | 你可能偶尔需要处理类似这样的问题:确定数组的键是否从索引 | |
| 190 | 你可能偶尔需要处理类似这样的问题:确定数组的键是否从索引 0 开始按数字顺序排列。例如 `json_encode` 需要决定将 json 转换为数组还是对象。 | |
| 195 | 191 | |
| 196 | 192 | |
| 197 | 193 | PHP 8.1添加了一个内置函数来确定数组是否是具有这些语义的列表: | … | … |
| 210 | 206 | array_is_list($alsoNotAList); // false |
| 211 | 207 | ``` |
| 212 | 208 | |
| 213 | ### | |
| 214 |
| |
| 215 | PHP中的类常量可以在继承过程中被覆盖 | |
| 209 | ### 最终类常量 RFC | |
| 210 | ||
| 211 | PHP中的类常量可以在继承过程中被覆盖: | |
| 216 | 212 | |
| 217 | 213 | ``` |
| 218 | 214 | class Foo | … | … |
| 226 | 222 | } |
| 227 | 223 | ``` |
| 228 | 224 | |
| 229 | 从PHP 8.1开始,您可以将这样的常量标记为 | |
| 225 | 从PHP 8.1开始,您可以将这样的常量标记为 `final`,以防止出现这种情况: | |
| 230 | 226 | |
| 231 | 227 | ``` |
| 232 | 228 | class Foo | … | … |
| 243 | 239 | |
| 244 | 240 | * * * * * |
| 245 | 241 | |
| 246 | ### | |
| 247 |
| |
| 248 | PHP 8.1增加了 | |
| 242 | ### 新的 `同步` 函数 RFC | |
| 243 | ||
| 244 | PHP 8.1增加了 `fsync` 函数和 `fdatync` 函数,强制将文件同步更改到磁盘,并确保操作系统写缓冲区在返回前已刷新。 | |
| 249 | 245 | |
| 250 | 246 | ``` |
| 251 | 247 | $file = fopen("sample.txt", "w"); |
| 252 | 248 | |
| 253 | fwrite($file, " | |
| 249 | fwrite($file, "一些内容"); | |
| 254 | 250 | |
| 255 | 251 | if (fsync($file)) { |
| 256 | echo " | |
| 252 | echo "文件已成功保存到磁盘"; | |
| 257 | 253 | } |
| 258 | 254 | |
| 259 | 255 | fclose($file); |
| 260 | 256 | ``` |
| 261 | 257 | |
| 262 | ||
| 263 | ||
| 264 | 因为磁盘同步是一个文件系统操作,所以`fsync`函数将只对普通文件流起作用。尝试同步非文件流将发出警告。 | |
| 265 | ||
| 266 | * * * * * | |
| 267 | ||
| 268 | ### 显式八进制整数文字表示法:RFC | |
| 269 | ||
| 270 | 您现在可以使用`0o`和`0O`来表示八进制数。前面用`0`作为数字前缀的表示法仍然有效。 | |
| 258 | 因为磁盘同步是一个文件系统的操作,所以 `fsync` 函数将只对普通文件流起作用。尝试同步非文件流将发出警告。 | |
| 259 | ||
| 260 | * * * * * | |
| 261 | ||
| 262 | ### 显式八进制整数文字表示法 RFC | |
| 263 | ||
| 264 | 您现在可以使用 `0o` 和 `0O` 来表示八进制数。前面用 `0` 当做前缀的表示法仍然有效。 | |
| 271 | 265 | |
| 272 | 266 | ``` |
| 273 | 267 | 016 === 0o16; // true | … | … |
| 276 | 270 | |
| 277 | 271 | ## 突破性变化 |
| 278 | 272 | |
| 279 | 虽然PHP8.1是一个小版本,但在技术上可能会有一些突破性的变化,也会有一些不赞成的意见。让我们逐一讨论。 | |
| 280 | ||
| 281 | * * * * * | |
| 282 | ||
| 283 | ### RFC的内部方法返回类型 | |
| 284 | ||
| 285 | 在升级到PHP 8.1时,您可能会遇到此弃用通知: | |
| 286 | ||
| 287 | ``` | |
| 288 | 返回类型应该与IteratorAggregate::getIterator():Traversable兼容, | |
| 289 | 或者应该使用 #[ReturnTypeWillChange] 属性暂时隐藏通知 | |
| 290 | ``` | |
| 291 | ||
| 292 | ||
| 273 | 虽然 PHP 8.1 是一个小版本,但在技术上可能会有一些突破性的变化,当然也有一些反对意见。我们来逐一讨论。 | |
| 274 | ||
| 275 | * * * * * | |
| 276 | ||
| 277 | ### 内部方法返回类型 RFC | |
| 278 | ||
| 279 | 在升级到PHP 8.1时,你可能会见到此弃用通知: | |
| 280 | ||
| 281 | ``` | |
| 282 | Return type should either be compatible with IteratorAggregate::getIterator(): Traversable, | |
| 283 | or the #[ReturnTypeWillChange] attribute should be used to temporarily suppress the notice | |
| 284 | ``` | |
| 293 | 285 | |
| 294 | 286 | 你可能注意到了,这个错误信息会在使用 `phpunit/phpunit`、`symfony/finder` 和其他流行的开源包中出现。实际是因为内部函数开始使用正确的返回类型。如果想要从标准库(如`IteratorAggregate`)中继承一个类,这时还需要添加返回类型。 |
| 295 | 287 | … | … |
| 309 | 301 | } |
| 310 | 302 | ``` |
| 311 | 303 | |
| 312 | ||
| 313 | ||
| 314 | 304 | 或者你可以添加返回类型: |
| 315 | 305 | |
| 316 | 306 | ``` | … | … |
| 343 | 333 | by_ref($GLOBALS); |
| 344 | 334 | ``` |
| 345 | 335 | |
| 346 | ||
| 347 | ||
| 348 | Nikita分析了Packagist上排名前2000的包, 只发现了23个会受到这一变化的影响。我们可以得出结论,这种技术突破性变化的影响将很小,这就是为什么内部决定在PHP 8.1中添加它。请记住,考虑到这一变化对我们代码中的每个地方都有积极的性能影响,我们中的大多数人都将从这一更改中获益。 | |
| 336 | Nikita 分析了 Packagist 上排名前 2000 的包,只发现了 23 个会受此变化影响的案例。我们可以得出结论,这种技术突破性变化的影响将是很小的,这也是为什么内部决定将它们添加到 PHP 8.1。请记住,大多数开发者都将从中获益,对我们代码产生的积极影响将无处不在。 | |
| 349 | 337 | |
| 350 | 338 | ### 资源到对象的迁移 |
| 351 | 339 | |
| 352 | 这些变化是将所有资源转换为专用对象的长期愿景的一部分。你可以在[这里](https://github.com/php/php-tasks/issues/6)了解更多。 | |
| 353 | ||
| 354 | **带有 `finfo` 对象的Fileinfo函数** | |
| 355 | ||
| 356 | `finfo_file`、`finfo_open`等函数用于接受和返回资源。从PHP8.1开始,它们可以使用所有的[`finfo`](https://www.php.net/manual/en/class.finfo.php)对象。 | |
| 357 | ||
| 358 | ||
| 340 | 这些变化是将所有资源转换为专用对象的长期愿景的一部分。你可以在 [这里](https://github.com/php/php-tasks/issues/6) 了解更多。 | |
| 341 | ||
| 342 | **带有 `finfo` 对象的 Fileinfo 函数** | |
| 343 | ||
| 344 | `finfo_file`、`finfo_open` 等函数用于接受和返回资源。从 PH P8.1 开始,它们可以使用所有的 [`finfo`](https://www.php.net/manual/en/class.finfo.php) 对象。 | |
| 359 | 345 | |
| 360 | 346 | **具有`IMAPConnection` 对象的 IMAP 函数** |
| 361 | 347 | |
| 362 | 就像 fileinfo 的 | |
| 363 |
| |
| 364 | * * * * *
| |
| 365 |
| |
| 366 | ### 不推荐 | |
| 367 |
| |
| 368 | 这个更改很简单 | |
| 348 | 就像 fileinfo 的变更一样,像 `imap_body` 和 `imap_open` 的 IMAP 函数不再使用资源的方式。 | |
| 349 | ||
| 350 | * * * * * | |
| 351 | ||
| 352 | ### 不推荐在内部函数中将 null 传递给不可为 null 的参数 RFC | |
| 353 | ||
| 354 | 这个更改很简单:内部函数当前可以为非 null 参数接受 `null`,这个 RFC 反对这种行为。例如,现在这样是可以的: | |
| 369 | 355 | |
| 370 | 356 | ``` |
| 371 | 357 | str_contains("string", null); |
| 372 | 358 | ``` |
| 373 | 359 | |
| 374 | 在 PHP 8.1中,这些类型的错误将抛出一个弃用警告,在 PHP 9中,它们将被转换为类型错误。 | |
| 375 | ||
| 376 | * * * * * | |
| 377 | ||
| 378 | ### 自动复活 `false` rfc | |
| 360 | 在 PHP 8.1中,这样的错误将抛出一个弃用警告,在 PHP 9 中,它们将变为类型错误。 | |
| 361 | ||
| 362 | * * * * * | |
| 363 | ||
| 364 | ### 从 `false` 自动变为非 false (Autovivification) RFC | |
| 365 | ||
| 366 | > Autovivification 是 perl 中自造的词,但是在很多语言中都有应用。参考 [Perl的autovivification特性](https://www.cnblogs.com/f-ck-need-u/p/9718238.html#perl%E7%9A%84autovivification%E7%89%B9%E6%80%A7)、[维基百科 Autovivification](https://en.wikipedia.org/wiki/Autovivification#PHP)(译者注) | |
| 379 | 367 | |
| 380 | 368 | 来自 RFC: |
| 381 | 369 | |
| 382 | > PHP 本身允许自动复活(根据 falsey 值自动创建数组)。这个特性非常有用,在许多 PHP 项目中都有使用,特别是在变量未定义的情况下。但是,有一点奇怪,允许从 false 和 null 值创建数组。 | |
| 383 | ||
| 384 | ||
| 370 | >PHP 天生支持 autovivification(自动从假的值中创建数组)。这个特性十分有用,特别是当值没有定义的时候。并且已经用在了很多 PHP 项目中。然而,有一点很奇怪,它居然允许从一个 false 和 null 创建一个数组。 | |
| 385 | 371 | |
| 386 | 372 | 您可以在 RFC 页面上阅读详细信息。总之,不推荐使用这种行为: |
| 387 | 373 | … | … |
| 397 | 383 | |
| 398 | 384 | ### 其他小变化 |
| 399 | 385 | |
| 400 | 对于每一个发布版本, | |
| 401 |
| |
| 402 | 以下是一些最重要的变化 | |
| 386 | 对于每一个发布版本,语言上都会有一些非常小的变化。所有这些都被列在 GitHub 的 [升级指南](https://github.com/php/php-src/blob/master/UPGRADING)和 [弃用的 RFC](https://wiki.php.net/rfc/deprecations_php_8_1) 中,如果你想知道每一个小细节,一定要去看看。 | |
| 387 | ||
| 388 | 以下是一些最重要的变化: | |
| 403 | 389 | |
| 404 | 390 | - `MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH` 最大长度不再有效果 |
| 405 | 391 | - `MYSQLI_STORE_RESULT_COPY_DATA` 不再有效 |
| 406 | 392 | - PDO::ATTR_STRINGIFY_FETCHES 现在也可以用布尔值了 |
| 407 | 393 | - 当使用模拟准备语句时,PDO MySQL 和 Sqlite 结果集中的整数和浮点数将使用本地 PHP 类型而不是字符串返回 |
| 408 | 394 | - 像 `htmlspecialchars` 和 `htmlentities` 这样的函数在默认情况下也会转换为 `'` ; 格式不正确的 utf-8也会被 Unicode字符替换,而不是产生一个空字符串 |
| 409 | - `hash`、 `hash_file` 和 `hash _ init` 有一个额外的参数添加到它们中,称为 `$options`,它的默认值为`[]` ,因此不会影响代码 | |
| 410 | - `MurmurHash3` 和 `xxHash`新的支持 | |
| 411 | ||
| 412 | * * * * * | |
| 413 | ||
| 414 | ||
| 415 | ||
| 416 | 现在就是这样,记住我会在一年中定期更新这篇文章,所以如果你想要随时了解的话,一定要[订阅](https://stitcher.io/newsletter/subscribe)。你对 PHP 8.1感到兴奋吗?在[Twitter](https://twitter.com/brendt_gd)上告诉我! | |
| 395 | - `hash`、 `hash_file` 和 `hash _ init` 将会加入一个额外的参数 `$options`,它的默认值为`[]` ,不会影响已有代码 | |
| 396 | - 新支持 `MurmurHash3` 和 `xxHash` | |
| 397 | ||
| 398 | * * * * * | |
| 399 | ||
| 400 | ||
| 401 | 就是这样了,记住我会在一年中定期更新这篇文章,所以如果你想要随时得到更新的话,一定要 [订阅](https://stitcher.io/newsletter/subscribe)。你对 PHP 8.1 感到兴奋吗?在 [Twitter](https://twitter.com/brendt_gd) 上告诉我吧! | |
| 417 | 402 |
关于 LearnKu