PHP版本
PHP8.1.x版本特性
# 新特性 #### 1. 新增字符串类型键的数组解包 在 array 定义时,用 ... 前缀的一个 array 可以被展开到当前位置。 只有实现了 Traversable 的数组和对象才能被展开。 PHP 7.4.0 开始可以使用 ... 解包 array。 它可以多次使用,在 ... 操作符前后都可以添加常规元素。 ```php <?php $arr1 = [1, 'a' => 'b']; $arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd'] ``` #### 2. 参数展开后命名参数 现在可以在参数展开后为命名参数。 例如: foo(...$args, named: $arg). #### 3. 文件上传新增 full-path 键 现在文件上传新增了额外的 full_path 键, 这包含了上传文件的完整路径(不仅仅是返回路径中的文件名部分)。 这是为了与 “upload webkitdirectory” 结合使用。 #### 4. 新增枚举支持 枚举,或称 “Enum”,能够让开发者自定义类型为一系列可能的离散值中的一个。 在定义领域模型中很有用,它能够“隔离无效状态”)。 枚举以各种不同功能的形式出现在诸多语言中。 在 PHP 中, 枚举是一种特殊类型的对象。Enum 本身是一个类(Class), 它和 class、interface、trait 共享同样的命名空间。 也能用同样的方式自动加载。 一个 Enum 定义了一种新的类型,它有固定、数量有限、可能的合法值。 最常见的枚举例子是内置的 boolean 类型, 该枚举类型有两个有效值 true 和 false。 Enum 使开发者能够任意定义出用户自己的、足够健壮的枚举。 ```php <?php enum Suit{ case Hearts; case Diamonds; case Clubs; case Spades; } ``` #### 5. 新增纤程Fibers 纤程(Fiber)表示一组有完整栈、可中断的功能。 纤程可以在调用堆栈中的任何位置被挂起,在纤程内暂停执行,直到稍后恢复。 纤程可以暂停整个执行堆栈,所以该函数的直接调用者不需要改变调用这个函数的方式。 你可以在调用堆栈的任意地方使用 Fiber::suspend() 中断执行(也就是说,Fiber::suspend() 的调用位置可以在一个深度嵌套的函数中,甚至可以不存在)。 与无栈的 Generator 不同, 每一个 Fiber 拥有自己的调用栈,并允许在一个深度前度的函数调用中将它们暂停。 声明了中断(interruption)点的函数(即调用 Fiber::suspend()) 不需要改变自己的返回类型,不像使用 yield 一样需要返回一个 Generator 实例。 纤程可以在任意函数调用中被暂停,包括那些在 PHP VM 中被调用的函数。 例如被用于 array_map() 的函数或者提供 Iterator 实例以被 foreach 调用的方法。 纤程一旦被暂停,可以使用 Fiber::resume() 传递任意值、或者使用 Fiber::throw() 向纤程抛出一个异常以恢复运行。这个值或者异常将会在 Fiber::suspend() 中被返回(抛出)。 >注意: 由于当前限制,不能在对象的析构函数中打开或关闭纤程。 ```php <?php $fiber = new Fiber(function (): void { $value = Fiber::suspend('fiber'); echo "Value used to resume fiber: ", $value, PHP_EOL; }); $value = $fiber->start(); echo "Value from fiber suspending: ", $value, PHP_EOL; $fiber->resume('test'); ``` #### 6. First Class 可调用语法 现在可调用闭包可以使用 myFunc(...) 语法创建,与 Closure::fromCallable('myFunc') 效果一样。 >注意: ... 是语法的一部分,不是省略。 ```php <?php class Foo { public function method() {} public static function staticmethod() {} public function __invoke() {} } $obj = new Foo(); $classStr = 'Foo'; $methodStr = 'method'; $staticmethodStr = 'staticmethod'; $f1 = strlen(...); $f2 = $obj(...); // invokable object $f3 = $obj->method(...); $f4 = $obj->$methodStr(...); $f5 = Foo::staticmethod(...); $f6 = $classStr::$staticmethodStr(...); // traditional callable using string, array $f7 = 'strlen'(...); $f8 = [$obj, 'method'](...); $f9 = [Foo::class, 'staticmethod'](...); ``` #### 7. 新增交集类型 交集类型接受满足多个类类型声明的值,而不是单个值。交集类型中的每个类型由 & 符号连接。因此,类型 T、U 和 V 组成的交集类型将写成 T&U&V。 >警告:交集类型不能与联合类型 一起使用 联合类型:联合类型接受多个不同类型的值,而不是单个类型。联合类型中的每个类型由 | 符号连接。因此类型 T、U 和 V 的联合类型写成 T|U|V。如果其中一种类型是交集类型,需要使用括号括起来,在 DNF 中写成:T|(X&Y) #### 8. Never 类型 新增一个新的仅仅返回类型 never。它表示函数要么 exit() ,要么抛出异常,要么不会终止 #### 9. 在初始化中 new 现在可以将 new ClassName() 语句作为参数、静态变量、初始化全局常量、注解参数的默认值。现在对象可以作为 define() 的参数了。 #### 10. Readonly 属性 自 PHP 8.1.0 起,可以使用 readonly 修饰符声明属性,防止初始化后修改属性。 ```php <?php class Test { public readonly string $prop; public function __construct(string $prop) { // 初始化正常。 $this->prop = $prop; } } ``` #### 11. Final 类常量 PHP 8.1.0 起,可用final修饰常量。修饰后不许更改! ```php class Foo{ final public const X = "foo"; } ``` >注意: 属性和常量不能被定义为 final,只有类、方法、常量(PHP 8.1.0 起)才能被定义为 final。 从 PHP 8.0.0 起,除了构造函数之外,私有方法也不能声明为 final 。 #### 12. PDO 新增 PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY 常量,可用于指定可加载的文件目录。 这个设置只在禁用 PDO::MYSQL_ATTR_LOCAL_INFILE 时才有意义,这种情况下允许加载任意的文件目录。 #### 13. MySQLi - 新增 INI 设置 mysqli.local_infile_directory 新增 mysqli.local_infile_directory INI 设置,该设置可以指定允许加载文件的目录。这个设置只在禁用 mysqli.allow_local_infile 时才有意义,这种情况下允许加载任意的文件目录。 - execute 可绑定参数 现在可以将参数以数组的形式传递给 mysqli_stmt::execute() 来绑定参数。所有值都以字符串的形式绑定。仅支持普通数组。当使用 libmysqlclient 编译 MySQLi 时,这个新功能不可使用。 ```php <?php $stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)'); $stmt->execute([1, $username]); ``` - 新方法 mysqli_result::fetch_column() 新增 mysqli_result::fetch_column() 方法可以从结果集中获取单个标量值。 新方法接收 int 类型、从 0 开始,可选的 column 参数,用于从指定行获取数据。 ```php <?php $result = $mysqli->query('SELECT username FROM users WHERE id = 123'); echo $result->fetch_column(); ``` # 新函数 #### 1. PHP 核心中新增的函数 - array_is_list() #### 2. GD - imagecreatefromavif() - imageavif() #### 3. MySQLi - mysqli_result::fetch_column() - mysqli_fetch_column() #### 4. 进程控制 - pcntl_rfork() #### 5. 反射 - ReflectionFunctionAbstract::getClosureUsedVariables() #### 6. 常规 - fsync() - fdatasync() # 不向后兼容的变更 #### 1. $GLOBALS 访问限制 现在访问 $GLOBALS 数组受到一些限制。 对单个数组元素的读写访问 $GLOBALS['var'] 与之前一样。 也将继续支持对整个数组 $GLOBALS 的只读访问。 但是,不再支持对整个 $GLOBALS 数组的写访问。 例如,array_pop($GLOBALS) 将返回错误。 #### 2. 在继承的方法中 static 变量的用法 当一个方法使用继承的(而不是重写的)静态变量时,继承的方法将与父级共享这个静态变量。 这意味着方法中的静态变量现在的使用方式与静态属性一样。 ```php <?php class A { public static function counter() { static $counter = 0; $counter++; return $counter; } } class B extends A {} var_dump(A::counter()); // int(1) var_dump(A::counter()); // int(2) var_dump(B::counter()); // int(3),之前是 int(1) var_dump(B::counter()); // int(4),之前是 int(2) ``` #### 3. 返回类型与内部类的兼容性 大多数非 Final 的内部方法现在要求重写方法声明一个可兼容的返回类型,否则在继承时会给出方法废弃的提示。 如果由于 PHP 跨版本兼容性的问题,导致不能为重写方法声明返回类型,则可以添加 ReturnTypeWillChange 注解来取消废弃提示。 #### 4. 新的关键词 现在 readonly 是一个关键词。不过,它仍然可以被用作函数名。 never 现在是保留字,所以不能用于类,接口或者 trait,也禁止在命名空间中使用。 #### 5.Resource 类型迁移为 Object 类型 一些 资源(resource) 类型已被迁移到 object 类型。 要检查返回值,应该从 is_resource() 检查是否为资源,更改为检查返回值是否等于 false。 #### 6. MySQLi 现在 mysqli_fetch_fields() 和 mysqli_fetch_field_direct() 对于 max_length 将返回 0 值。 这一信息可以迭代结果集来计算,并获取最大长度。这是之前 PHP 内部的做法。 常量 MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 不再生效。 常量 MYSQLI_STORE_RESULT_COPY_DATA 不再生效。 传递给 mysqli::store_result() 的 mode 参数的所有值不再生效。 现在 mysqli::connect() 成功时返回 true 而不再返回 null。 默认错误处理模式已经由 silent 变成了 exceptions,更多详情及如何设置该属性请参见 MySQLi reporting mode 。 要恢复之前的行为习惯,请使用: mysqli_report(MYSQLI_REPORT_OFF); #### 7. OpenSSL 现在 EC 私钥将以 PKCS#8 格式导出,而非像其他秘钥那样的传统格式。 现在 openssl_pkcs7_encrypt() 和 openssl_cms_encrypt() 将默认使用 AES-128-CBC,而非 RC2-40。 RC2-40 加密被认为是不安全的,OpenSSL 3 默认不启用。 #### 8.MySQL 驱动 现在,当使用模拟预处理时,结果集中的整数及浮点数将会以 PHP 原始类型返回,而不是以 string 类型返回。 这与原生的预处理方式一样。 之前的行为方式可以通过 PDO::ATTR_STRINGIFY_FETCHES 恢复。 # PHP 8.1.x 废弃的功能 #### 1. 实现无 \_\_serialize() 和 \_\_unserialize() 的 Serializable 如果不用兼容 PHP 7.4 以前的版本,就只需要实现新的方法,否则需要同时实现两个方法。 #### 2. 将 null 传递给内置函数的非 null 值参数 为了与用户定义的函数行为保持一致,标量类型需要被明确标记为允许为 null,内置函数的标量类型默认情况下允许为 null 的行为已被废弃。 #### 3. 不兼容从 float 到 int 的隐式转换 从 float 隐式转换为 int 将会导致精度的丢失,目前这种行为已被废弃。 这将影响到 array 中的键、严格模式下 int 类型的声明以及对 int 的操作。 #### 4.在 trait 上调用 static 元素 在 trait 上直接调用 static 方法、直接访问 static 属性的行为已被废弃。静态方法和属性只能在使用了 trait 的类上被访问。 #### 5.在 \__sleep() 中返回非 array 类型值 在 \__sleep() 中返回一个非 array 类型的值现在将会产生一个诊断。 #### 6.MySQLi mysqli_driver::$driver_version 属性已被废弃。它是无意义且过时的,使用 PHP_VERSION_ID 来代替。 使用 mysqli 参数来调用 mysqli::get_client_info() 或 mysqli_get_client_info() 已被废弃。请不带任何参数调用 mysqli_get_client_info() 来获取客户端类库的版本信息。 mysqli::init() 方法已被废弃。使用 parent::\__construct() 来代替对 parent::init() 的调用。 #### 7. 常规 对一个对象调用 key()、current()、 next()、prev()、 reset()、end() 已被废弃。对一个对象应优先使用 get_mangled_object_vars(),或使用 ArrayIterator。 INI 配置项 auto_detect_line_endings 已被废弃。如有必要,可以手动处理 "\r" 换行符。 FILE_BINARY 和 FILE_TEXT 常量已被废弃。它们从未产生过任何作用。
顶部
收展
底部
[TOC]
目录
关于VC和线性安全的选择
PHP5.6版本
PHP6版本去哪儿了?
PHP7.0.x版本特性
PHP7.1.x版本特性
PHP7.2.x版本特性
PHP7.3.x版本特性
PHP7.4.x版本特性
PHP8.0.x版本特性
PHP8.1.x版本特性
相关推荐
PHP基础
PHP函数
PHP设计模式
PHP算法