php8更新,PHP 8 中新特性以及重大调整

76cfe4f841453a6851a77b61ac84fc03.png

PHP 8,PHP 的一个新的大版本,预计将于2020年12月3日发布,这意味着将不会有 PHP 7.5 版本。PHP8目前正处于非常活跃的开发阶段,所以在接下来的几个月里,情况可能会发生很大的变化。

在这篇文章中,我会维持一个最新的清单列表,列出预计会出现的新特性、性能提升和突破性的变化。由于 PHP 8 是一个新的大版本,因此您的代码被破坏的可能性更高。如果您始终保持运行 PHP 的最新版本,那么升级相对来说就会轻松很多,因为在7. *版本中,大多数重大更改均已弃用。

除重大更改外,PHP 8还带来了一些不错的新功能,比如说 JIT编译器, 联合类型, 属性,以及更多。

新特性

从新特性开始,请记住 PHP8 仍处于活动开发阶段,因此此列表将随着时间的推移而增长。

联合类型

考虑到 PHP 动态语言类型的特性,现在很多情况下,联合类型都是很有用的。联合类型是两个或者多个类型的集合,表示可以使用其中任何一个类型。public function foo(Foo|Bar $input): int|float;

请注意,联合类型中不包含 void,因为void 表示的含义是“根本没有返回值”。 另外,可以使用 |null 或者现有的 ? 表示法来表示包含 nullable 的联合体 :public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;

JIT

JIT — just in time — 编译器虽然不总是在 Web 请求的上下文中,但是有望显着地提高性能。目前还没有完成任何准确的基准测试,但是肯定会到来。

如果您想进一步了解JIT对PHP的作用,可以阅读我写过的另一篇文章此处。

属性

属性在其他语言中通常被称为 注解 ,提供一种在无需解析文档块的情况下将元数据添加到类中的方法。

快速浏览一下,这里有一份来自 RFC 的属性示例:use App\Attributes\ExampleAttribute;

<>

class Foo

{

<>

public const FOO = 'foo';

<>

public $x;

<>

public function foo(<> $bar) { }

}<>

class ExampleAttribute

{

public $value;

public function __construct($value)

{

$this->value = $value;

}

}

如果您想深入了解属性如何工作以及如何构建自己的属性,您可以在此博客上阅读有关深入属性的信息。

新增 static 返回类型

尽管已经可以返回 self,但是 static 直到 PHP 8 才是有效的返回类型 。考虑到 PHP 具有动态类型的性质,此功能对于许多开发人员将非常有用。class Foo

{

public function test(): static

{

return new static();

}

}

新增 mixed 类型

有人可能将其称为必要的邪恶:mixed 类型让许多人感觉十分混乱。然而,有一个很好的论据支持去实现它:缺少类型在 PHP 中会导致很多情况:函数不返回任何内容或返回空值

我们需要多种类型的一种类型

我们需要的是PHP中不能进行类型提示的类型

因为上述原因,添加 mixed 类型是一件很棒的事儿。mixed 本身代表下列类型中的任一类型:array

bool

callable

int

float

null

object

resource

string

请注意,mixed 不仅仅可以用来作为返回类型,还可以用作参数和属性类型。

另外,还需要注意,因为 mixed 类型已经包括了 null,因此 mixed 类型不可为空。下面的代码会触发致命错误:// 致命错误:混合类型不能为空,null已经是混合类型的一部分。

function bar(): ?mixed {}

throw 表达式

该RFC将throw从一个语句更改为一个表达式,这使得可以在很多新地方抛出异常:$triggerError = fn () => throw new MyError();

$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');

弱映射

基于在 PHP 7.4 中新增的 弱引用 RFC,PHP 8 中新增了 WeakMaps(弱映射)的实现。 WeakMaps(弱映射)在保持对一些对象的引用的同时,并不会组织这些对象被垃圾回收机制处理 。

以ORM为例,它们通常实现保存对实体类的引用的缓存,从而提高实体类之间关联的性能。 只要缓存中存在对这些实体类的引用,那么这些类就无法被垃圾回收机制回收,尽管除了缓存中,已经没有别处再引用这些实体类,它们依然不会被垃圾处理机制处理。

如果这个缓存层使用了弱引用和弱映射,那么 PHP 将会在这些实体类没有任何其他引用时,对其进行垃圾回收。 尤其是对于 ORMs,它可以管理一个请求中的数百个(如果不是数千个)实体;弱映射可以提供一种更好的、对资源更友好的方式来处理这些对象。

下面是弱映射基本的例子,摘抄自 RFC :class Foo

{

private WeakMap $cache;

public function getSomethingWithCaching(object $obj): object

{

return $this->cache[$obj]

??= $this->computeSomethingExpensive($obj);

}

}

允许对对象使用 ::class

一个很小但是很有用的新特性:现在可以在对象上使用 :: class ,而不必在对象上使用 get_class() ,它的工作方式跟 get_class() 相同。$foo = new Foo();

var_dump($foo::class);

Non-capturing catches

在PHP 8 之前,无论何时你想要捕获一个异常,你都需要先将其存储到一个变量中,不管这个变量你是否会用到。通过 Non-capturing catches 你可以忽略变量,所以替换下面的代码:try {

// Something goes wrong

} catch (MySpecialException $exception) {

Log::error("Something went wrong");

}

你现在可以这么做:try {

// Something goes wrong

} catch (MySpecialException) {

Log::error("Something went wrong");

}

请注意,必须始终指定类型,不允许将 catch 留空,如果你想要捕获所有类型的异常和错误,需要使用 Throwable 作为捕获类型。

参数列表中的尾部逗号

当调用函数时已经支持尾部逗号,但是参数列表中仍然缺少尾随逗号支持。现在PHP8中允许这样做,这意味着您可以执行以下操作:public function(

string $parameterA,

int $parameterB,

Foo $objectfoo,

) {

// …

}

从接口创建DateTime 对象

你已经可以使用 DateTime::createFromImmutable($immutableDateTime) 从 DateTimeImmutable 对象创建一个 DateTime 对象, 而另一种方法则更加取巧。通过添加DateTime::createFromInterface()和DatetimeImmutable::createFromInterface()现在有一种通用的方法可以将DateTime和DatetimeImmutable对象相互转换。DateTime::createFromInterface(DateTimeInterface $other);

DateTimeImmutable::createFromInterface(DateTimeInterface $other);

新增 Stringable接口

Stringable接口可用于键入提示任何字符串或实现__ toString()的内容。此外,每当一个类实现__ toString()时,它就会自动实现后台接口,而无需手动实现。class Foo

{

public function __toString(): string

{

return 'foo';

}

}

function bar(Stringable $stringable) { /* … */ }

bar(new Foo());

bar('abc');

新增 str_contains() 函数 rfc

有些人可能会说这是早该发生的,但我们最终不必再依赖strpos来知道一个字符串是否包含另一个字符串。

无需这样做:if (strpos('string with lots of words', 'words') !== false) { /* … */ }

你可以这样做:if (str_contains('string with lots of words', 'words')) { /* … */ }

新增 str_starts_with() 和 str_ends_with() 函数

这是另外两个早该出现的函数,现在已在核心函数中添加了这两个函数。str_starts_with('haystack', 'hay'); // true

str_ends_with('haystack', 'stack'); // true

新增 fp() 函数

新的fp()函数的作用类似于fmod()和intp()函数,它们可以除以0。视情况而定,将得到INF,-INF或NAN。

新增 get_debug_type() 函数

get_debug_type()返回变量的类型,听起来好像跟 gettype() 的作用一样啊?get_debug_type() 可以为数组,字符串,匿名类和对象返回更有用的输出信息。

例如,在类\ Foo \ Bar上调用gettype()将返回object,而使用get_debug_type()将返回类名。

如下表:Valueget_debug_type()gettype()0intinteger

0.1floatdouble

trueboolboolean

falseboolboolean

“hello”string

[]array

nullnullNULL

A class with name “Foo\Bar”Foo\Barobject

An anonymous classclass@anonymousobject

A resourceresource (xxx)resource

A closed resourceresource (closed)

可以在RFC中找到get_debug_type()和gettype()之间的差异的完整列表。

新增 get_resource_id() 函数

资源是PHP中的特殊变量,指的是外部资源。一个示例是MySQL连接,另一个是文件句柄。

这些资源中的每一个都分配有一个ID,然而在这之前,如果想获取某资源的ID,唯一方法是将资源转换为int:$resourceId = (int) $resource;

PHP 8添加了get_resource_id()函数,使此操作更加明显且类型安全:$resourceId = get_resource_id($resource);

Traits 改进中的抽象方法

Traits 可以指定必须由使用它们的类所实现的抽象方法。需要注意的是: 在 PHP 8 之前,尚未验证这些方法已经实现的标识。以下内容有效:trait Test {

abstract public function test(int $input): int;

}

class UsesTrait

{

use Test;

public function test($input)

{

return $input;

}

}

当使用 Traits 并实现其抽象方法时,PHP 8将执行适当的方法进行标识验证抽象方法是否确实被实现。这意味着您需要编写以下代码:class UsesTrait

{

use Test;

public function test(int $input): int

{

return $input;

}

}

token_get_all() rfc的对象实现

token_get_all()函数返回一个值数组,该RFC使用PhpToken :: getAll()方法新增了PhpToken类。此实现适用于对象而不是普通值。它消耗更少的内存,并且更易于阅读。

可变语法调整

在RFC中:“统一变量语法RFC解决了PHP变量语法中的许多不一致之处。该RFC旨在解决一小部分被忽略的情况。”

内部函数的类型注解

许多人 投入 了为所有内部函数添加适当的类型注释的工作。这是一个长期存在的问题,最终可以通过以前版本中对PHP所做的所有更改来解决。这意味着内部函数和方法将在反射中具有完整的类型信息。

重大变化

如前所述:这是一个重大更新,因此会有重大变化。最好的办法是查看 升级 文档中所列的重大变化的完整列表。

许多这些突破性的更改在以前的 7.* 版本中已被弃用,因此如果你多年来一直保持 PHP 在最新状态,升级到 PHP 8 应该没那么难。

一致的类型错误 rfc

之前版本在出现类型错误时,PHP 中的用户定义函数已经会抛出 TypeErrors,但是内部函数不会这么做,而是发出警告并返回 null。从 PHP 8 开始,内部函数的行为已变得和用户定义函数一致。

重新分类的引擎警告 rfc

许多以前仅触发警告或通知的错误已转换为适当的错误。以下警告已更改。变量未定义:Error 异常代替通知

数组索引未定义:警告代替通知

除以零:pisionByZeroError 异常代替警告

尝试添加/移除非对象的属性 '%s' :Error 异常代替警告

尝试修改非对象的属性 '%s' :Error 异常代替警告

尝试分配非对象的属性 '%s' :Error 异常代替警告

从空值创建默认对象:Error 异常代替警告

尝试获取非对象的属性 '%s' :警告代替通知

未定义的属性:%s::$%s:警告代替通知

无法添加元素到数组,因为下一个元素已被占用:Error 异常代替警告

无法在非数组变量中销毁偏移量:Error 异常代替警告

无法将标量值用作数组:Error 异常代替警告

只有数组和 Traversables 可以被解包:TypeError 异常代替警告

为 foreach() 提供了无效的参数:TypeError 异常代替警告

偏移量类型非法:TypeError 异常代替警告

isset 或 empty 中的偏移量类型非法:TypeError 异常代替警告

unset 中的偏移量类型非法:TypeError 异常代替警告

数组到字符串的转换:警告代替通知

资源 ID#%d 用作偏移量,转换为整数 (%d):警告代替通知

发生字符串偏移量转换:警告代替通知

未初始化的字符串偏移量:%d:警告代替通知

无法将空字符串分配给字符串偏移量:Error 异常代替警告

提供的资源不是有效的流资源:TypeError 异常代替警告

@ 运算符不再使致命错误不提醒

此更改可能会使 PHP 8 之前的版本被 @ 隐藏的错误再次显示出来。请确保在生产服务器上设置了 display_errors=Off !

默认错误报告级别

现在的默认错误报告级别是 E_ALL 而不是之前的除 E_NOTICE 和 E_DEPRECATED 的所有内容。这意味着可能会弹出许多错误,这些错误以前曾被忽略,尽管在 PHP 8 之前的版本中可能已经存在。

默认 PDO 错误模式 rfc

根据RFC:当前 PDO 的默认错误模式为静默。这意味着当出现 SQL 错误时,除非开发人员实现了自己的显式错误处理,否则不会发出任何错误或警告,也不会引发任何异常。

此 RFC 将在 PHP 8 中将默认 PDO 错误模式 改为PDO::ERRMODE_EXCEPTION 。

串联优先级 rfc

在 PHP 7.4 中已废弃的同时,此变更开始生效。如果你像这样子书写:echo "sum: " . $a + $b;

PHP 以前会如是理解:echo ("sum: " . $a) + $b;

PHP 8 将这么做故理解为此:echo "sum: " . ($a + $b);

更严格的算术和位运算类型检查

PHP 8 以前,算术或位运算符用于数组、资源或对象是可接受的。现在不再可接受,并会抛出一个 类型错误 :[] % [42];

$object + 4;

反射方法签名变更

反射类的 3 个方法签名已变更:ReflectionClass::newInstance($args);

ReflectionFunction::invoke($args);

ReflectionMethod::invoke($object, $args);

现在已变成:ReflectionClass::newInstance(...$args);

ReflectionFunction::invoke(...$args);

ReflectionMethod::invoke($object, ...$args);

升级指南指定,如果要扩展这些类,并且仍想同时支持 PHP 7 和 PHP 8,则允许以下签名:ReflectionClass::newInstance($arg = null, ...$args);

ReflectionFunction::invoke($arg = null, ...$args);

ReflectionMethod::invoke($object, $arg = null, ...$args);

几个弃用

在PHP 7. * 的开发期间,添加了几个弃用版本,这些弃用已于 PHP 8 最终确定。PHP 7.2 中的弃用

PHP 7.3 中的弃用

PHP 7.4 中的弃用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Javascript学习之函数(function)

http://www.cnblogs.com/royalroads/p/4418587.html 在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例&#xff0c;而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。 一 函数的声明方式 //1.函数声…

jquery弹出可关闭遮罩提示框

jquery CSS3遮罩弹出层动画效果&#xff0c;使用非常简单&#xff0c;就两个标签&#xff0c;里面自定义内容和样式&#xff0c;四种常见效果&#xff0c;懂的朋友还可以修改源代码修改成自己想要的效果效果展示 http://hovertree.com/texiao/jquery/85/代码如下&#xff1a; &…

用于Spring JPA2后端的REST CXF

在本演示中&#xff0c;我们将使用spring / jpa2后端生成一个REST / CXF应用程序。 该演示演示了分钟项目的轨迹REST-CXF 。 演示2中的模型保持不变。 浓缩保持不变。 但是轨道改变了 添加的是2层&#xff1a; 在JPA2之上具有弹簧集成的DAO层 具有JAX-RS批注的REST-CXF层…

php与服务器关系,php与web服务器关系

1.什么是cgi程序&#xff0c;cgi与fastcgi的区别CGI的中文名称是通用网关接口&#xff0c;是外部应用程序与web服务器之间的接口标准。CGI规范允许web服务器执行外部程序&#xff0c;并将它们的输出发送给web浏览器。而fastcgi则是一个常驻型的cgi&#xff0c;它可以一直执行着…

POJ 3468 A Simple Problem with Integers(线段树:区间更新)

http://poj.org/problem?id3468 题意&#xff1a; 给出一串数&#xff0c;每次在一个区间内增加c&#xff0c;查询[a,b]时输出a、b之间的总和。 思路&#xff1a; 总结一下懒惰标记的用法吧。 比如要对一个区间范围内的数都要加c&#xff0c;在找到这个区间之后&#xff0c;本…

php 新浪url,PHP URL函数详解

php url函数:parse_url()parse_url(PHP 3, PHP 4, PHP 5)parse_url -- 解析 URL&#xff0c;归来其构成局部解释array parse_url ( string url )本函数解析一个 URL 并归来一个关系数组&#xff0c;包括在 URL 中揭示的各种构成局部。本函数不是用来检讨给定 URL 的合法性的&am…

完整的WebApplication JSF EJB JPA JAAS –第1部分

这篇文章将是迄今为止我博客中最大的一篇文章&#xff01; 我们将看到完整的Web应用程序。 最新的技术将完成此工作&#xff08;直到今天&#xff09;&#xff0c;但是我将给出一些提示以显示如何使本文适用于较旧的技术。 在本文的结尾&#xff0c;您将找到要下载的源代码。 您…

Ajax和JavaScript的区别

javascript是一种在浏览器端执行的脚本语言&#xff0c;Ajax是一种创建交互式网页应用的开发技术 &#xff0c;它是利用了一系列相关的技术其中就包括javascript。Javascript是由网景公司开发的一种脚本语言&#xff0c;它和sun公司的java语言是没有任何关系的&#xff0c;它们…

大一

以后准备开始ACM的题目啦转载于:https://www.cnblogs.com/Aiden-/p/6562038.html

概念验证:玩! 构架

我们正在开始一个新项目&#xff0c;我们必须选择Web框架。 我们的默认选择是grails&#xff0c;因为团队已经拥有使用它的经验&#xff0c;但是我决定给Play&#xff01; 和Scala有机会。 玩&#xff01; 有很多很酷的东西&#xff0c;在我的评估中&#xff0c;它得到了很多加…

ldap统一用户认证php,针对LDAP服务器进行身份认证

Symfony提供了不同的方法来配合LDAP服务器使用。Security组件提供&#xff1a;ldap user provider&#xff0c;使用的是form_login_ldap authentication provider&#xff0c;用于针对一台使用了表单登录的LDAP服务器。同所有其他user provider一样&#xff0c;它可以同任何aut…

每天CookBook之JavaScript-039

IIFE的使用<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>039</title> </head> <body></body> <script type"text/javascript"> (function () {var i 0;fu…

Day-6:创建计算字段

字段&#xff1a;基本上与列的意思相同&#xff0c;经常互换使用&#xff0c;计算字段是运行时在SELECT语句内创建的&#xff0c;不实际存在于数据库表中。 拼接字段&#xff1a;将值联结到一起构成单个值 SQL中的SELECT语句中可以使用或||操作符拼接&#xff0c;但mysql中必须…

使用Hibernate加载或保存图像-MySQL

本教程将引导您逐步了解如何使用Hibernate从数据库&#xff08; MySQL &#xff09;保存和加载图像。 要求 对于此示例项目&#xff0c;我们将使用&#xff1a; Eclipse IDE &#xff08;您可以使用自己喜欢的IDE&#xff09;&#xff1b; MySQL &#xff08;您可以使用任何…

javaweb回顾第四篇Servlet异常处理

前言&#xff1a;很多网站为了给用户很好的用户体验性&#xff0c;都会提供比较友好的异常界面&#xff0c;现在我们在来回顾一下Servlet中如何进行异常处理的。 1&#xff1a;声明式异常处理 什么是声明式&#xff1a;就是在web.xml中声明对各种异常的处理方法。 是通过<er…

java开发cs教程,日常运维(一)

w命令&#xff1a;用于查看系统负载、显示已经登陆系统的用户列表&#xff0c;并显示用户正在执行的指令等信息第一行从左面开始显示的信息依次为&#xff1a;时间&#xff0c;系统运行时间&#xff0c;登录用户数&#xff0c;平均负载。第二行开始以及下面所有的行&#xff0c…

coursera 《现代操作系统》 -- 第五周 同步机制(1)

临界区块&#xff08;Critical section&#xff09;指的是一个访问共用资源&#xff08;例如&#xff1a;共用设备或是共用存储器&#xff09;的程序片段&#xff0c;而这些共用资源有无法同时被多个线程访问的特性。&#xff08;不是字面意思的一个区域&#xff0c;是程序片段…

java.lang.NoClassDefFoundError:如何解决–第2部分

本文是我们的NoClassDefFoundError故障排除系列的第2部分。 看一下第1部分 。 它将重点介绍最简单的NoClassDefFoundError问题类型。 本文对于Java初学者来说是理想的选择&#xff0c;我强烈建议您自己编译并运行示例Java程序。 今后将使用以下书写格式&#xff0c;并为您提供&…

Android开发技术周报 Issue#34

教程 Google Develop for Android 系列 前几天在G上看到Google Developers站点&#xff0c;有一个Android系列的文章&#xff0c;分享到个人微博&#xff0c;周末闲来没事就学写了下&#xff0c;把它们简单的翻译了下&#xff0c;没想到一发不可收拾&#xff0c;六篇文章全部都…

php进度条插件,分享8款优秀的 jQuery 加载动画和进度条插件_jquery

加载动画和进度条在网站和 Web 应用中的使用非常流行。虽然网速越来越快&#xff0c;但是我们的网站越来越复杂&#xff0c;同时用户对网站的使用体验的要求也越来越高。在内容加载缓慢的时候&#xff0c;使用时尚的加载动画和进度条告诉用户还有内容正在加载是一种非常好的方式…