php7.4.x~php8.0.x 新特性
PHP 核心中的新特性
命名参数
新增 命名参数 的功能。
// array_fill(int $start_index, int $count, mixed $value): array
// 使用顺序传递参数:
array_fill(0, 100, 50);
// 使用命名参数:
array_fill(start_index: 0, count: 100, value: 50);
// 参数顺序不同的示例(同上例)
array_fill(value: 50, count: 100, start_index: 0);
注解
新增注解的功能。
语法:注解声明总是以 #[ 开头,以 ] 结尾来包围。 内部则是一个或以逗号包含的多个注解。
注解是一种在类、属性、方法等声明上方添加元数据的方式,可以在运行时通过反射 API 读取和处理。
// a.php
namespace MyExample;
use Attribute;
#[Attribute]
class MyAttribute
{
const VALUE = 'value';
private $value;
public function __construct($value = null)
{
$this->value = $value;
}
}
// b.php
namespace Another;
use MyExample\MyAttribute;
#[MyAttribute]
#[\MyExample\MyAttribute]
#[MyAttribute(1234)]
#[MyAttribute(value: 1234)]
#[MyAttribute(MyAttribute::VALUE)]
#[MyAttribute(array("key" => "value"))]
#[MyAttribute(100 + 200)]
class Thing
{
}
#[MyAttribute(1234), MyAttribute(5678)]
class AnotherThing
{
}
// 读取注解的示例:
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
class MyAnnotation {
public $value;
public function __construct($value) {
$this->value = $value;
}
}
#[MyAnnotation('Class Annotation')]
class MyClass {
#[MyAnnotation('Property Annotation')]
public $property;
#[MyAnnotation('Method Annotation')]
public function myMethod() {
// 方法体
}
}
$reflectionClass = new ReflectionClass(MyClass::class);
// 获取类上的注解
$classAttributes = $reflectionClass->getAttributes(MyAnnotation::class);
foreach ($classAttributes as $attribute) {
/** @var MyAnnotation $instance */
$instance = $attribute->newInstance();
echo "Class Annotation: " . $instance->value . PHP_EOL;
}
// 获取属性上的注解
$property = $reflectionClass->getProperty('property');
$propertyAttributes = $property->getAttributes(MyAnnotation::class);
foreach ($propertyAttributes as $attribute) {
/** @var MyAnnotation $instance */
$instance = $attribute->newInstance();
echo "Property Annotation: " . $instance->value . PHP_EOL;
}
// 获取方法上的注解
$method = $reflectionClass->getMethod('myMethod');
$methodAttributes = $method->getAttributes(MyAnnotation::class);
foreach ($methodAttributes as $attribute) {
/** @var MyAnnotation $instance */
$instance = $attribute->newInstance();
echo "Method Annotation: " . $instance->value . PHP_EOL;
}
构造器属性提升
新增在构造函数中声明类的属性的支持。
// 使用构造器参数
class Point {
protected int $x;
protected int $y;
public function __construct(int $x, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
}
// **使用构造器属性提升**
class Point2 {
public function __construct(protected int $x, protected int $y = 0) {
}
public function getX() {
return $this->x;
}
}
// 两个参数都传入
$p1 = new Point2(1, 5);
// 仅传入必填的参数。 $y 会默认取值 0。
$p2 = new Point2(2);
// 使用命名参数(PHP 8.0 起):
$p3 = new Point2(y: 5, x: 3);
var_dump($p1->getX());
var_dump($p2->getX());
var_dump($p3->getX());
当构造器参数带修饰符时,PHP 会同时把它当作对象属性和构造器参数, 并赋值到属性。 构造器可以是空的,或者包含其他语句。
并非所有参数都需要提升。可以混合提升或不提升参数作为属性,也不需要按顺序。 提升后的参数不影响构造器内代码调用。
联合类型
新增 联合类型。
class A {}
function f(A|string $c) {
var_dump($c);
}
f(new A); // object(A)#1 (0) {}
f('a'); // a
null 类型语法糖,单个基本类型声明可以通过在类型前添加问号(?)来标记可为 null,?T 和 T|null 是相同的。
// 使参数可以为 null 的旧方式
class A {}
function f(A $c = null) {
var_dump($c);
}
f(new A); // object(A)#1 (0) {}
f(null); // null
class A {}
function f(?A $c) {
var_dump($c);
}
f(new A); // object(A)#1 (0) {}
f(null); // null
match 表达式
新增 match 表达式。
match表达式和 switch 语句类似, 都有一个表达式主体,可以和多个可选项进行比较。 与 switch 不同点是,它会像三元表达式一样求值。 与 switch 另一个不同点,它的比较是严格比较( =)而不是松散比较()。
$food = 'cake';
$return_value = match ($food) {
'apple' => 'This food is an apple',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
};
var_dump($return_value);
Nullsafe 运算符
新增 Nullsafe 运算符(?->)。
对象引用解析(dereference)为 null 时不抛出异常,而是返回 null。 并且如果是链式调用中的一部分,剩余链条会直接跳过。
$repository = null;
// Nullsafe 运算符
$result = $repository?->getUser(5)?->name;
var_dump($result);
// 上边代码等价于以下代码
if (is_null($repository)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}
其他新特性
- 新增 WeakMap 类。
WeakMap 是将对象作为 key 来访问的 map(或者说字典), WeakMap 中的对象 key 不影响对象的引用计数。
class A {
public function __destruct() {
echo "A!\n";
}
}
$wm = new WeakMap();
$o = new stdClass;
$wm[$o] = new A;
var_dump(count($wm));
unset($o);
var_dump(count($wm));
新增 ValueError 类。
当参数类型正确但是值不正确的时候会抛出 ValueError。现在,只要类型兼容,任意数量的函数参数都可以用一个可变参数替换。例如允许编写下面的代码:
class A {
public function method(int $many, string $parameters, $here) {}
}
class B extends A {
public function method(...$everything) {}
}
- static(“后期静态绑定”中)可以作为返回类型:
class Test {
public function create(): static {
return new static();
}
}
- 现在可以通过 $object::class 获取类名,返回的结果和 get_class($object) 一致。
class A {
public function method(int $many, string $parameters, $here) {}
}
$a = new A();
var_dump($a::class);
var_dump(get_class($a));
new、instanceof 可用于任何表达式,用法为 new (expression)(...$args) 和 $obj instanceof (expression)。
?
添加对一些变量语法一致性的修复,例如现在能够编写 Foo::BAR::$baz。
添加 Stringable interface,当类定义 __toString() 方法后会自动实现该接口。
Trait 可以定义私有抽象方法(abstract private method)。类必须实现 trait 定义的该方法。
可作为表达式使用 throw。使得可以编写以下用法:
$fn = fn() => throw new Exception('Exception in arrow function');
$user = $session->user ?? throw new Exception('Must have user');
- 参数列表中的末尾逗号为可选。
function functionWithLongSignature(
Type1 $parameter1,
Type2 $parameter2, // <-- 这个逗号也被允许了
) {
- 现在允许 catch (Exception) exception 而无需捕获到变量中。
try {
throw new \Exception('AAA!');
} catch (\Exception) {
}
支持 mixed 类型。
mixed 类型接受每个值。等同于联合类型 object|resource|array|string|float|int|bool|null。自 PHP 8.0.0 起可用。
在类型理论中,mixed 是顶级类型。这意味着其它所有类型都是它的子类型。父类中声明的私有方法不在对子类中的方法执行任何继承规则(final private 构造方法除外)。下列示例说明删除了那些限制:
class ParentClass {
private function method1() {}
private function method2() {}
private static function method3() {}
// private final function method4() {}
}
class ChildClass extends ParentClass {
// 现在允许以下所有内容,即使修饰符与父类中的私有方法不同。
public function method1() {}
public static function method2() {}
public function method3() {}
public function method4() {}
}
新增 get_resource_id() 函数,返回值跟 (int) $resource 相同。其在更清晰的 API 下提供了相同的功能。
新增 InternalIterator 类。
标准库
新增 str_contains()、str_starts_with() 和 str_ends_with(),分别检查 haystack 是否包含 needle 或以 needle 开头/结尾。
新增 fdiv() 在 IEEE 754 语义下执行浮点除法。认为除以零已经明确定义,将返回 Inf、-Inf 或 NaN。
$b = fdiv(10, 0);
echo $b; // INF
新增 get_debug_type() 返回对错误消息有用的类型。与 gettype() 不同的是,它使用规范的类型名称,为对象返回类名,为资源表示资源类型。
printf() 和相关函数现在支持 %h 和 %H 格式说明符。它们与 %g 和 %G 相同,但始终使用 "." 作为小数点分隔符,而不是通过 LC_NUMERIC 区域确定。
现在,printf() 和相关函数支持使用 "*" 作为宽度或精度,此时宽度/精度将作为参数传递给 printf。这也允许在 %g、%G、%h 和 %H 中使用精度 -1。例如,以下代码可用于重现 PHP 的默认浮点数格式化:
printf("%.*H", (int) ini_get("precision"), $float);
printf("%.*H", (int) ini_get("serialize_precision"), $float);
- 现在,proc_open() 支持伪终端(PTY)描述符。以下将 stdin、stdout 和 stderr 附加到同一个 PTY.
$proc = proc_open($command, [['pty'], ['pty'], ['pty']], $pipes);
- proc_open() 现在支持套接字对描述符。以下将独立的套接字对附加到 stdin、stdout 和 stderr.
$proc = proc_open($command, [['socket'], ['socket'], ['socket']], $pipes);
排序函数现在已稳定,这意味着相等的元素比较将保留其原始顺序。
array_diff() 和 array_intersect() 及其变体现在可以接受单个数组作为参数。
// 如果 $excludes 为空也可以:
array_diff($array, ...$excludes);
// 如果 $arrays 仅包含单个数组也可以:
array_intersect(...$arrays);
var_dump(array_diff(['a','b']));
- ob_implicit_flush() 的 flag 参数已经从接受 int 变更为接受 bool。
DOM
Filter
Enchant
FPM
Hash
LDAP
OPcache
OpenSSL
正则表达式(兼容 Perl)
反射
SQLite3
Tokenizer
Zip
PHP 8.0 废弃的功能
PHP 核心中废弃的功能
- 如果带有默认值的参数后面跟着一个必要的参数,那么默认值就会无效。这在 PHP 8.0.0 中已被废弃,通常可以通过删除默认值,不影响现有功能:
function test($a = [], $b) {} // 之前
function test($a, $b) {} // 之后
PHP8.2:
Deprecated: Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter
标准库
- 排序比较函数现在返回 true 或者 false 将会引发弃用警告,应替换为返回小于、等于或者大于零的 int 值。
// 替换
usort($array, fn($a, $b) => $a > $b);
// 为
usort($array, fn($a, $b) => $a <=> $b);
Enchant
LibXML
PGSQL/PDO PGSQL
Zip
反射
https://www.php.net/manual/zh/migration80.new-features.php
https://www.php.net/manual/zh/migration80.deprecated.php
php7.4.x~php8.0.x 新特性的更多相关文章
- php5.3到php7.0.x新特性介绍
<?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...
- php7函数,声明,返回值等新特性介绍
使用 ... 运算符定义变长参数函数 (PHP 5 >= 5.6.0, PHP 7) 现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数. functi ...
- paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较
paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...
- NodeJS 框架 Express 从 3.0升级至4.0的新特性
NodeJS 框架 Express 从 3.0升级至4.0的新特性 [原文地址:√https://scotch.io/bar-talk/expressjs-4-0-new-features-and-u ...
- 相比于python2.6,python3.0的新特性。
这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...
- MySQL 8.0 InnoDB新特性
MySQL 8.0 InnoDB新特性 1.数据字典全部采用InnoDB引擎存储,支持DDL原子性.crash safe,metadata管理更完善 2.快速在线加新列(腾讯互娱DBA团队贡献) 3. ...
- Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性
Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性 1.1. Jquery1.12 jQuery 2.2 和 1.12 新版本发布 - OPEN资讯.h ...
- [PHP] 从PHP 5.6.x 移植到 PHP 7.0.x新特性
从PHP 5.6.x 移植到 PHP 7.0.x 新特性: 1.标量类型声明 字符串(string), 整数 (int), 浮点数 (float), 布尔值 (bool),callable,array ...
- servlet3.0 的新特性之二注解代替了web.xml配置文件
servlet3.0 的新特性: 注解代替了 web.xml 文件 支持了对异步的处理 对上传文件的支持 1.注解代替了配置文件 1.删除了web.xml 文件 2. 在Servlet类上添加@Web ...
- C# 6.0/7.0 的新特性
转眼C#语言都已经迭代到7.0版本了,很多小伙伴都已经把C# 7.0 的新特性应用到代码中了,想想自己连6.0的新特性都还很少使用,今天特意搜集了一下6.0和7.0的一些新特性,记录一下,方便查阅. ...
随机推荐
- CSS & JS Effect – Breadcrumb Navigation 面包屑
介绍 Breadcrumb 长这样 主要就是让用户清楚自己在哪个 page, 然后可以轻松返回上一页. Step by Step HTML <div class="container& ...
- BFS 马的遍历————洛谷p1443
马的遍历 题目描述 有一个 \(n \times m\) 的棋盘,在某个点 \((x, y)\) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步. 输入格式 输入只有一行四个整数,分别为 ...
- 记一次Razor Pages无法编译问题及解决
解决方案写在前面:更新Visual Studio及相关组件,本人版本自17.8.0更新至17.11.4 缘起于公司的一个业务接口,在有一些信息需要在应用内嵌的webview中展示,信息不少,涉及的前端 ...
- XYD1006CSPS
T1 密钥 [关键结论,模拟,枚举] Description 给定两个长度为 \(n\) 的 \(01\) 序列 \(a\),\(b\),每个位置都有一个权值 \(c\), 每次操作可以将 \(a\) ...
- JNI和HAL 的区别
JNI (Java Native Interface) 和 HAL (Hardware Abstraction Layer) 在 Android 系统中都扮演着与本地代码交互的重要角色,但它们的功能和 ...
- 活动预告 | 中国数据库联盟(ACDU)中国行第四站定档西安,邀您探讨数据库前沿技术
作为墨天轮社区与中国数据库联盟的品牌活动之一,[ACDU 中国行]已走过深圳.杭州.成都三大城市,在线下汇集数据库领域的行业知名人士,共同探讨数据库前沿技术及其应用,促进行业发展和创新,同时也为开发者 ...
- 忽略某个已经托管给git的文件,防止二次提交
# 执行命令将文件加入不提交队列 git update-index --assume-unchanged 你的文件路径 # 执行命令将文件取消加入不提交队列 git update-index --no ...
- C#扩展方法 Where Any Count Signal SignalOrDefault First 等方法的使用
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...
- 3.flask 源码解析:路由
目录 一.flask 源码解析:路由 1.1 构建路由规则 1.2 werkzeug 路由逻辑 1.3 flask 路由实现 1.4 match 实现 Flask 源码分析完整教程目录:https:/ ...
- Linux命令netstat查看端口使用方法
[redis@fgedu180 ~]$ netstat -an|grep 6379 tcp 0 0 192.168.4.180:6379 0.0.0.0:* LISTEN