热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP8.1发布,新特性一览

PHP8.1发布,新特性一览|PHP8.1于今日发布了。让我们一一介绍所有新功能、性能改进、更改和弃用。PHP8.1新特性与每个版本

PHP 8.1 于今日发布了。让我们一一介绍所有新功能、性能改进、更改和弃用。

PHP8.1新特性

与每个版本一样,PHP 8.1 增加了一些不错的新特性。

#枚举(eNum) rfc

枚举在 PHP 8.1 中已经添加!如果您不确定它们的用途,可以在此处阅读有关它们的信息。

添加枚举将是 PHP 的重大改进。为了让您快速预览它们的外观,这里有一个代码示例:

enum Status {
  case Pending;
  case Active;
  case Archived;
}

这就是它们的使用方式:

class Post
{
    public function __construct(
        private Status $status = Status::Pending;
    ) {}

    public function setStatus(Status $status): void
    {
        // …
    }
}

$post->setStatus(Status::Active);

您可以在这篇文章中找到有关如何使用枚举的深入分析。


#纤程(Fibers) rfc

纤程——又名“绿色线程” ——是一种管理并行性的低级机制。您可能不会直接在您的应用程序中使用它们,但是像 Amphp 和 ReactPHP 这样的框架会大量使用它们。它为PHP添加了异步机制

这是使用纤维的简单示例:

$fiber = new Fiber(function (): void {
    $valueAfterResuming = Fiber::suspend('after suspending');
    
    // … 
});
 
$valueAfterSuspending = $fiber->start();
 
$fiber->resume('after resuming');

如果您想了解更多有关 Fiber 的信息,以及它们能做什么和不能做什么,您可以阅读这篇文章。


#性能改进 PR

Dmitry Stogov 对 opcache 进行了一些改进,他称之为“继承缓存”。此功能允许缓存类之间的链接,就像从 PHP 7.4 开始可以预加载链接的类一样。

由于这一变化,Dmitry 报告了 5% 到 8% 的性能提升,这是 PHP 8.1 中需要注意的一个很好的小细节。另对框架的性能测试见 https://github.com/kocsismate/php-version-benchmarks/blob/main/docs/results/2021_11_11_09_20_1_aws_arm64_c6g_4xlarge/result.md,此报告有20-30%性能提升。

笔者注:本要亲自对laravel9框架,进行了php8.1和php8.0的性能对比,实测php8.1比php8.0性能提升达到80%!!,如有兴趣,你可以亲自测试一下PHP8.1的性能。


#使用字符串键解包数组 rfc

PHP 7.4 中已经允许数组解包,但它只适用于数字键。之前不支持字符串键的原因是因为对于如何合并数组重复项没有达成任何共识。RFC 通过遵循array_merge语义解决了这个问题:

$array1 = ["a" => 1];

$array2 = ["b" => 2];

$array = ["a" => 0, ...$array1, ...$array2];

var_dump($array); // ["a" => 1, "b" => 2]

#在初始化程序中使用new rfc

这个 RFC 允许你new在函数定义中使用关键字作为默认参数,以及在属性参数和其他地方。

class MyController {
    public function __construct(
        private Logger $logger = new NullLogger(),
    ) {}
}

您可以在这篇专门的文章中阅读有关此功能的所有信息。


#只读属性 rfc

类属性可以标记为只读,这意味着它们只能写入一次。

class PostData {
    public function __construct(
        public readonly string $title,
        public readonly DateTimeImmutable $date,
    ) {}
}

在初始化后尝试更改只读属性将导致错误:

$post = new Post('Title', /* … */);

$post->title = 'Other';

Error: Cannot modify readonly property Post::$title

如果您想深入了解有关 readonly 属性的更多信息,可以阅读我的文章。


#First-class callable rfc

您现在可以通过调用可调用对象并将其...作为参数传递来从可调用对象创建闭包:

function foo(int $a, int $b) { /* … */ }

$foo = foo(...);

$foo(a: 1, b: 2);

#交集类型 rfc

您已经了解PHP 8.0 中的联合类型,交集类型也是一个类似的特性。联合类型要求输入是给定类型之一,交集类型要求输入是所有指定类型。当您使用大量接口时,交集类型特别有用:

function generateSlug(HasTitle&HasId $post) {
    return strtolower($post->getTitle()) . $post->getId();
}

如果您喜欢这种编程风格,您需要创建一个新接口Sluggable并在 中实现它$post,交集类型摆脱了这种开销。


#新never类型rfc

never类型可用于指示函数将实际停止程序流程。这可以通过抛出异常、调用exit或其他类似函数来完成。

function dd(mixed $input): never
{
    // dump
    
    exit;
}

never不同之处void在于void仍然允许程序继续。这似乎是一个新奇的功能,但它实际上对静态分析器来说是一个非常有用的功能。


#新array_is_list函数rfc

您可能偶尔不得不处理这个问题:确定数组的键是否按数字顺序排列,从索引 0 开始。就像json_encode决定数组应该编码为数组还是对象一样。

PHP 8.1 添加了一个内置函数来确定数组是否是具有这些语义的列表:

$list = ["a", "b", "c"];

array_is_list($list); // true

$notAList = [1 => "a", 2 => "b", 3 => "c"];

array_is_list($notAList); // false

$alsOnotAList= ["a" => "a", "b" => "b", "c" => "c"];

array_is_list($alsoNotAList); // false

#最终类常量 rfc

PHP 中的类常量可以在继承过程中被覆盖:

class Foo
{
    public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
}

从 PHP 8.1 开始,您可以将这样的常量标记为final以防止出现这种情况:

class Foo
{
    final public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
    Fatal error: Bar::X cannot override final constant Foo::X
}

#新fsync函数rfc

PHP 8.1 添加了fsyncfdatasync函数以强制将文件更改同步到磁盘并确保操作系统写入缓冲区在返回之前已被刷新。

$file = fopen("sample.txt", "w");

fwrite($file, "Some content");

if (fsync($file)) {
    echo "File has been successfully persisted to disk.";
}

fclose($file);

由于磁盘同步是一种文件系统操作,因此该fsync功能仅适用于纯文件流。尝试同步非文件流将发出警告。


#显式八进制整数文字表示法 rfc

您现在可以使用0o0O来表示八进制数。前面通过在数字前面加上前缀的表示法0仍然有效。

016 === 0o16; // true
016 === 0O16; // true

#向后兼容性中断变化

虽然 PHP 8.1 是一个次要版本,但会有一些更改,这些更改在技术上可能是向后兼容性中断更改,也可能会被弃用。让我们一一讨论它们。


内部方法返回类型 rfc

升级到 PHP 8.1 时,您可能会遇到此弃用通知:

Return type should either be compatible with IteratorAggregate::getIterator(): Traversable, 
or the #[ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

您可能会注意到这个错误弹出使用的时候phpunit/phpunitsymfony/finder和其他一些流行的开源软件包。发生的事情是内部函数开始使用正确的返回类型。如果您要从标准库(如IteratorAggregate)扩展类,则还需要添加这些返回类型。

修复方法很简单:如果错误发生在第三方包中,请更新您的供应商代码(其中大多数已经在最新版本中修复)。如果您的代码中出现错误,您可以添加该ReturnTypeWillChange属性,在 PHP 9.0 之前抑制错误。这是一个扩展类的示例DateTime

class MyDateTime extends DateTime
{
    /**
     * @return DateTime|false
     */
    #[ReturnTypeWillChange]
    public function modify(string $modifier) 
    { 
        return false; 
    }
}

或者您可以简单地添加返回类型:

class MyDateTime extends DateTime
{
    public function modify(string $modifier): DateTime|false 
    { 
        return false; 
    }
}

#限制$GLOBALS使用rfc

对如何$GLOBALS使用的微小更改将对所有数组操作的性能产生重大影响。Nikita 在RFC 中很好地解释了问题和解决方案。更改意味着某些边缘情况无法再使用$GLOBALS. “不再支持写入作为一个整体的 $GLOBALS。以下所有内容都会产生编译时错误”:

$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);

最重要的是,通过$GLOBALS引用传递会产生一个运行时错误:

by_ref($GLOBALS); // Run-time error

Nikita 分析了 Packagist 上排名前 2000 的软件包,仅发现了 23 个会受此更改影响的案例。我们可以得出这样的结论——从技术上讲,这种变化的影响很小,这就是内部人员决定在 PHP 8.1 中添加它的原因。请记住,考虑到它在我们代码中无处不在的积极性能影响,我们中的大多数人都会因这种变化而获胜。


#资源到对象迁移

这些变化是将所有资源转换为专用对象的长期愿景的一部分。您可以在此处阅读更多相关信息。

Fileinfo 函数与finfo对象

类似于finfo_filefinfo_open用于接受和返回资源的函数。从 PHP 8.1 开始,它们可以处理finfo对象。

带有IMAPConnection对象的IMAP 函数

就像文件信息更改一样,IMAP 的功能类似于资源imap_bodyimap_open但不再使用资源


#弃用将 null 传递给内部函数的不可为 null 的参数 rfc

这个变化很简单:内部函数目前接受null不可为空的参数,这个 RFC 不赞成这种行为。例如,这是目前可能的:

str_contains("string", null);

在 PHP 8.1 中,这些类型的错误会抛出弃用警告,在 PHP 9 中它们将被转换为类型错误。


#Autovivification false rfc

来自 RFC:

PHP 本身允许Autovivification(从假值自动创建数组)。这个特性非常有用,在很多 PHP 项目中都有使用,尤其是在变量未定义的情况下。但是,允许从 false 和 null 值创建数组有一点奇怪。

您可以在 RFC 页面上阅读详细信息。总之,此行为已被弃用:

$array = false;

$array[] = 2;

Automatic conversion of false to array is deprecated

#其他小改动

每次发布时,都会对语言进行一些非常小的更改。所有这些都列在GitHub 上的升级指南和小的弃用 RFC 中,如果您想了解每一个小细节,请务必查看它。

以下是最重要变化的摘要:

  • MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 不再有效果
  • MYSQLI_STORE_RESULT_COPY_DATA 不再有效果
  • PDO::ATTR_STRINGIFY_FETCHES 现在也适用于布尔值
  • 当使用模拟的准备语句时,PDO MySQL 和 Sqlite 结果集中的整数和浮点数将使用原生 PHP 类型而不是字符串返回
  • htmlspecialcharshtmlentities现在这样的函数也'默认转义为'; 格式错误的 UTF-8 也将被替换为 unicode 字符,而不是导致空字符串
  • hashhash_filehash_init增加了一个额外的参数给他们所谓的$options,它有一个默认值[],这样就不会影响到你的代码
  • MurmurHash3和的新支持xxHash

 

更多更改请查看: https://php.watch/versions/8.1

最后更新于 2021年11月27日


推荐阅读
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • React基础篇一 - JSX语法扩展与使用
    本文介绍了React基础篇一中的JSX语法扩展与使用。JSX是一种JavaScript的语法扩展,用于描述React中的用户界面。文章详细介绍了在JSX中使用表达式的方法,并给出了一个示例代码。最后,提到了JSX在编译后会被转化为普通的JavaScript对象。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文整理了Java中com.evernote.android.job.JobRequest.getTransientExtras()方法的一些代码示例,展示了 ... [详细]
  • 本文介绍了在PostgreSQL中批量导入数据时的优化方法。包括使用unlogged表、删除重建索引、删除重建外键、禁用触发器、使用COPY方法、批量插入等。同时还提到了一些参数优化的注意事项,如设置effective_cache_size、shared_buffer等,并强调了在导入大量数据后使用analyze命令重新收集统计信息的重要性。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
author-avatar
mobiledu2502932307
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有