try {
// some code
} catch (FirstException | SecondException $e) {
// handle first and second exceptions
}
7.list()现在支持键。
现在,您可以在[]语法中指定键。这样可以使用非整数或非顺序键来解构数组。
$data = [
["id" => 1, "name" => 'Tom'],
["id" => 2, "name" => 'Fred'],
];
// list() style
list("id" => $id1, "name" => $name1) = $data[0];
// [] style
["id" => $id1, "name" => $name1] = $data[0];
// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
// logic here with $id and $name
}
// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
// logic here with $id and $name
}
8.支持负字符串偏移
对负字符串偏移量的支持已添加到 接受偏移量的 字符串操作函数中,以及 使用 []或{}的字符串索引中。在这种情况下,负偏移量解释为距字符串结尾的偏移量。
var_dump("abcdef"[-2]);
var_dump(strpos("aabbcc", "b", -3));
Closure 类中 引入了新的静态方法,以使 Closure对象。
class Test
{
public function exposeFunction()
{
return Closure::fromCallable([$this, 'privateFunction']);
}
private function privateFunction($param)
{
var_dump($param);
}
}
$privFunc = (new Test)->exposeFunction();
$privFunc('some value');
10.curl 现在支持 http/2 server push.
11.新的object类型
引入了 一种新的类型
function test(object $obj) : object
{
return new SplQueue();
}
test(new StdClass());
12. 扩展名加载
共享扩展名不再需要指定其文件扩展名(对于Unix是.so或对于Windows是.dll)。这在php.ini文件以及
13.抽像方法覆盖
现在,当抽象类扩展另一个抽象类时,可以重写抽象方法。
abstract class A
{
abstract function test(string $s);
}
abstract class B extends A
{
// overridden - still maintaining contravariance for parameters and covariance for return
abstract function test($s) : int;
}
14.参数类型扩大¶
现在可以忽略来自重写方法和接口实现的参数类型。由于参数类型是互变的,因此这仍然符合LSP。
interface A
{
public function Test(array $input);
}
class B implements A
{
public function Test($input){} // type omitted for $input
}
15.允许对分组名称空间使用尾随逗号¶
现在可以在PHP 7.0中引入尾随逗号到组使用语法中。
use Foo\Bar\{
Foo,
Bar,
Baz,
};
16.更灵活的Heredoc和Nowdoc语法¶
文档字符串的结束标记不再需要在分号或换行符之后。另外,可以在结束标记处缩进,在这种情况下,缩进将从文档字符串中的所有行中去除。
17.数组解构支持引用赋值
数组解构现在支持使用语法[&$ a,[$ b,&$ c]] = $ d的引用赋值 。
18.CompileError异常而不是一些编译错误¶
添加了一个新的CompileError异常,ParseError继承了该异常。现在,少量编译错误将引发CompileError 而不是生成致命错误。当前,这仅影响TOKEN_PARSE模式下可能引发的编译错误,但将来可能会转换更多错误。
19.现在允许在函数和方法调用中使用逗号结尾。
20.多字节字符串函数新功能¶
请参考https://php.p2hp.com/manual/en/migration73.new-features.php#migration73.new-features.mbstring
21.属性类型声明
类属性现在支持类型声明。
class User {
public int $id;
public string $name;
}
?>
22.箭头函数
箭头函数提供了用于定义具有隐式按值作用域绑定的函数的简写语法。
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>
23.有限返回类型协方差和参数类型逆变¶
现在,以下代码将起作用:
class A {}
class B extends A {}
class Producer {
public function method(): A {}
}
class ChildProducer extends Producer {
public function method(): B {}
}
?>
仅当使用自动加载时,才提供完全方差支持。在单个文件中,只能使用非循环类型引用,因为所有类在被引用之前都必须可用。
24.空合并赋值运算符¶
??=
代替如下写法:
$data['date'] = $data['date'] ?? new DateTime();
你可以这样做:
$data['date'] ??= new DateTime();
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>
25.数组内解包
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>
26.数值文字分隔符
数字文字可以在数字之间包含下划线。
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
?>
27.弱引用
弱引用使程序员可以保留对对象的引用,这不会阻止对象被破坏。
28.FFI外部函数接口
FFI是一个新扩展,它提供了一种简单的方法来调用本机函数,访问本机变量以及创建/访问C库中定义的数据结构。
29.预加载
预加载是PHP核心的一个惊人的补充,可以带来一些重大的性能改进。
简而言之:如果您今天使用的是框架,则必须在每次请求时加载和重新编译其文件。预加载允许服务器在启动时在内存中加载PHP文件,并使它们永久可用于所有后续请求。
性能提升当然需要付出代价:如果预加载文件的来源发生变化,则必须重新启动服务器。
此特性可以大幅提升IO性能,性能提升约30-50%,甚至更高
30.自定义对象序列化
添加了用于自定义对象序列化的新机制,该机制使用了两个新的魔术方法:__serialize 和__unserialize。
// Returns array containing all the necessary state of the object.
public function __serialize(): array;
// Restores the object state from the given data array.
public function __unserialize(array $data): void;
?>
新的序列化机制取代了
31.没有参数的数组合并函数¶
现在可以不带任何参数地调用array_merge(... $ arrays))结合使用时很有用。
32.在对象和数组类型转换中转换数字键
现在,在将数组转换为对象以及将对象转换为数组时(通过显式转换或通过
这意味着现在可以访问从数组转换为对象的整数(或字符串整数)键:
// array to object
$arr = [0 => 1];
$obj = (object)$arr;
var_dump(
$obj,
$obj->{'0'}, // now accessible
$obj->{0} // now accessible
);
现在可以访问从对象转换为数组的整数(或字符串整数)键:
// object to array
$obj = new class {
public function __construct()
{
$this->{0} = 1;
}
};
$arr = (array)$obj;
var_dump(
$arr,
$arr[0], // now accessible
$arr['0'] // now accessible
);
二.向后不兼容的改变
1.传递过少的函数参数¶
以前,如果调用的用户定义函数的参数太少,将发出警告。现在,此警告已升级为错误异常。此更改仅适用于用户定义的功能,不适用于内部功能。例如:
function test($param){}
test();
2.禁止动态调用范围内省函数
禁止动态调用某些函数(以 $ func()或array_map('extract',...)等形式)。这些功能检查或修改了另一个范围,并表现出模棱两可和不可靠的行为。函数如下
(function () {
$func = 'func_num_args';
$func();
})();
上面的示例将输出:
警告:无法在%s的第%d行动态调用func_num_args()
3.无效的类,接口和trait名称¶
以下名称不能用于命名类,接口或trait:
4.数字字符串转换现在符合科学计数法¶
现在,数字字符串的整数运算和转换都遵循科学计数法。这也包括(INT)转换操作,和以下函数
5.修复了mt_rand()算法¶
7.禁止标识符中的ASCII删除控制字符¶
ASCII删除控制字符(0x7F)不能再用于未加引号的标识符中。
8.不要在不完整的对象上调用析构函数
现在,对于在执行其构造函数期间引发异常的对象,永远不会调用析构函数。在以前的版本中,此行为取决于对象是否在构造函数外部引用(例如,通过异常回溯)。
9.call_user_func()处理引用参数
call_user_func() 现在始终在调用预期引用为参数的函数时生成警告。以前,这取决于呼叫是否完全限定。
此外,在这种情况下,call_user_func() 和call_user_func_array() 将不再中止函数调用。将发出"预期引用"警告,但呼叫将照常进行。
10.字符串不再支持空索引运算符
将空索引运算符应用于字符串(例如$ str [] = $ x)会引发致命错误,而不是无声地转换为数组。
11.通过对空字符串的字符串索引访问进行赋值
现在,按字符对空字符串进行字符串修改的工作方式类似于非空字符串,即,写入超出范围的偏移量时,将用空格填充字符串,其中非整数类型将转换为整数,并且仅分配字符串的第一个字符用来。以前,空字符串在其中被静默地视为一个空数组。
$a = '';
$a[10] = 'foo';
var_dump($a);
?>
上面的示例在PHP 7.0中的输出:
array(1){
[10] =>
字符串(3)“ foo”
}
以上示例在PHP 7.1中的输出:
字符串(11)“ f”
12.通过引用赋值在自动创建元素时的数组顺序已更改 ¶
通过在按引用分配中引用这些元素来自动创建这些元素时,数组中元素的顺序已更改。例如:
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>
上面的示例在PHP 7.0中的输出:
array(2){
[“”“] =>
&int(1)
[” b“] =>
&int(1)
}
以上示例在PHP 7.1中的输出:
array(2){
[“” b“] =>
&int(1)
[” a“] =>
&int(1)
}
13.相等元素的排序顺序
内部排序算法已得到改进,这可能导致元素的排序顺序与以前相比有所不同。
注意事项:不要依赖比较相等的元素的顺序;它可能随时更改。
14.unserialize()的$options参数
现在严格类型allowed_classes元素 ,即,如果给出除FALSEE_WARNING
15.DateTime构造函数包含微秒
日期时间和日期时间不可变现在正确合并微秒时,从当前时间构造,无论是显式还是使用相对字符串(例如"下个月的第一天")。这意味着两个新创建的实例的天真比较现在更有可能返回 FALSE 而不是 TRUE:
new DateTime() == new DateTime();
?>
16.致命错误到错误异常的转换¶
现在许多扩展中的致命错误将变为Error异常抛出。
17.词汇绑定变量不能重用名称
通过use构造 绑定到闭包的变量不能使用与任何superglobals,$ this或任何参数相同的名称 。例如,所有这些函数定义都将导致致命错误:
$f = function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};
18.JSON编码和解码
现在,解码一个空键将导致一个空的属性名称,而不是 _empty_作为属性名称。
var_dump(json_decode(json_encode(['' => 1])));
上面的示例将输出类似于以下内容的内容:
object(stdClass)#1(1){
[“”] =>
int(1)
}
当将JSON_UNESCAPED_UNICODE标志提供给
如果没有匹配项 ,则regs)的第三个参数现在将设置为空数组。以前,该参数不会被修改。
以前,-0。尽管根据IEEE 754浮点规范这是完全有效的,但对于以人类可读形式显示格式化的数字,这种奇怪的做法是不希望的。
var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"
21.禁止传递NULL给¶
以前,传递NULL给E_WARNING将改为输出。为了实现与以前相同的行为,应仅省略该参数。
22.计数不可数类型时警告
一个E_WARNING试图当现在将发射
var_dump(
count(null), // NULL is not countable
count(1), // integers are not countable
count('abc'), // strings are not countable
count(new stdclass), // objects not implementing the Countable interface are not countable
count([1,2]) // arrays are countable
);
The above example will output:
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
int(0)
int(1)
int(1)
int(1)
int(2)
23.已关闭资源的
以前,在封闭的资源上使用“未知类型”的字符串。现在,将返回一个字符串 “ resource(closed)”。
24.¶
以前,在__PHP_Incomplete_Class类上使用is_object()将返回 FALSE。现在,将返回 TRUE。
25.检查traits的默认属性值
对默认traits属性值的兼容性检查将不再执行强制转换
26."object"用作类名
object名称以前在PHP 7.0中被软保留。现在,这是硬保留的,禁止将其用作类,特征或接口名称。
27.¶SORT_STRING参数
虽然SORT_STRING 以前复制的阵列和移除的非唯一的元素(不事后包装阵列),现在一个新的数组是通过将独特的元素构建的。这可能导致不同的数字索引。
28.
该%运算符。例如,bcmod('4','3.5')现在返回 0.5而不是1。
29.散列函数和非加密散列值¶
JSON_OBJECT_AS_ARRAY现在用于如果所述第二参数(assoc)是NULL。以前, JSON_OBJECT_AS_ARRAY总是被忽略。
由
由zone元素现在代表秒而不是分钟,并且其符号反转。例如-120 现在是7200。
33.Heredoc / Nowdoc结尾标签解释¶
由于引入了灵活的heredoc / nowdoc语法,因此在正文中包含结尾标签的doc字符串可能会导致语法错误或解释更改。例如:
$str = <<
abcdefg
FOO
FOO;
?>
缩进的FOO以前没有任何特殊意义。现在将其解释为heredoc字符串和以下FOO的结尾;将导致语法错误。始终可以通过选择字符串内容中未出现的结束标签来解决此问题。
34.Switch中的continue问题警告
现在,针对开关控制流结构的continue语句将生成警告。在PHP中,此类 continue语句等效于 break,而 在其他语言中,它们的行为与continue 2相同。
while ($foo) {
switch ($bar) {
case "baz":
continue;
// Warning: "continue" targeting switch is equivalent to
// "break". Did you mean to use "continue 2"?
}
}
?>
35.ArrayAccess上整数字符串键的严格解释
类型为$ obj [“ 123”]的数组访问,其中 $ obj实现ArrayAccess并且 “ 123”是整数$ obj-> offsetGet(“ 123”)将而不是$ obj-> offsetGet(123)被调用 。这与非文学作品的现有行为相匹配。数组的行为不会受到任何影响,它们会继续将整数字符串键隐式转换为整数。
36.静态属性不再由引用分配分隔
在PHP中,除非在子类中显式覆盖静态属性,否则静态属性在继承的类之间共享。但是,由于存在实现工件,因此可以通过分配引用来分离静态属性。此漏洞已得到修复。
class Test {
public static $x = 0;
}
class Test2 extends Test { }
Test2::$x = &$x;
$x = 1;
var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now: int(1), int(1)
?>
37.通过数组和属性访问返回引用是立即展开
现在,将数组访问和属性访问返回的引用展开为访问的一部分。这意味着不再可能在访问和使用访问值之间修改引用:
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
?>
这使引用和非引用的行为保持一致。请注意,在单个表达式内读取和写入值仍然是未定义的行为,将来可能会再次更改。
38.raversables的参数解包与非整数key不再支持
参数解压缩停止了与带有非整数键的Traversable一起使用。以下代码偶然在PHP 5.6-7.2中工作。
function foo(...$args) {
var_dump($args);
}
function gen() {
yield 1.23 => 123;
}
foo(...gen());
?>
39.image / bmp而不是 image / x-ms-bmp,因为前者已在IANA上注册(请参阅»RFC 7903)。
40.
41.IMAP, POP3 and NNTP¶
默认情况下,禁用rsh / ssh登录。如果要启用它们,请使用imap.enable_insecure_rsh。请注意,IMAP库它们传递给前不过滤的邮箱名RSH / SSH 命令,因此不受信任的数据传递给有此功能 RSH / SSH启用是不安全的。
42.多字节字符串
由于增加了对命名捕获的支持,使用命名捕获的mb_ereg _ *() 模式将表现出不同的行为。特别是命名捕获将成为匹配的一部分,并且命名捕获。
43.MySQL改进的扩展
现在,准备好的语句可以正确报告带有小数点说明符的DATETIME,TIME和 TIMESTAMP列的小数秒 (例如 ,使用微秒时为TIMESTAMP(6))。以前,小数秒部分只是从返回值中省略了。
44.MySQL函数(PDO_MYSQL)
现在,准备好的语句可以正确报告带有小数点说明符的DATETIME,TIME和 TIMESTAMP列的小数秒 (例如 ,使用微秒时为TIMESTAMP(6))。以前,小数秒部分只是从返回值中省略了。请注意,这仅会影响已关闭模拟准备的PDO_MYSQL的使用(例如,使用本机准备功能)。使用具有PDO::ATTR_EMULATE_PREPARES= TRUE (默认设置)的连接的语句不受已修复的错误的影响,并且已经从引擎获取了正确的小数秒值。
45.反射
反射导出到字符串现在分别使用 int和bool而不是 integer和boolean。
46.标准PHP库(SPL)
如果SPL自动加载器引发异常,将不会执行以后的自动加载器。以前,所有自动加载器均已执行,并且异常被链接在一起。
47.SimpleXML
现在, 涉及SimpleXML对象的数学运算会将文本视为
48.非数组的数组式访问
现在,尝试将$ null [“ key”])将生成一个通知。
49.get_declared_classes() 函数不再返回尚未实例化的匿名类。
50.fn关键字
fn现在是保留关键字。特别是,它不能再用作函数或类名。它仍然可以用作方法或类常量名称。
51.文件末尾的<?php标记
文件末尾的
52.序列化
o序列化格式已被删除。由于PHP从未生产过它,因此可能只会破坏手工制作的字符串的反序列化。
52.密码算法常量
密码哈希算法标识符现在是可为空的字符串,而不是整数。
PASSWORD_DEFAULT是int 1;现在是NULL
PASSWORD_BCRYPT是int 1;现在是字符串“ 2y”
PASSWORD_ARGON2I是int 2;现在是字符串“ argon2i”
PASSWORD_ARGON2ID是int 3;现在是字符串“ argon2id”
正确使用常量PASSWORD_DEFAULT,PASSWORD_BCRYPT,PASSWORD_ARGON2I和PASSWORD_ARGON2ID的应用程序将继续正常运行。
如果操作失败,FALSE。以前返回空字符串或0。EAGAIN / EWOULDBLOCK不被视为失败。
现在,这些功能还会引起故障通知,例如在尝试写入只读文件资源时
55.日期和时间
DateInterval对象的 比较(使用==,
56.MySQLi
取而代之的是公开的mysqli :: $ stat属性。
57.标准PHP库(SPL)
现在,在ArrayObject实例上 调用ArrayObject 本身(或子类)的属性。以前,除非 指定了标志,否则它返回包装的数组/对象的值。 ArrayObject::STD_PROP_LIST
其他受影响的操作是:
ReflectionObject :: getProperties()
可能有其他人将对象属性作为列表进行处理。
(数组)演员表不受影响。它们将继续返回包装的数组或ArrayObject 属性,具体取决于是否使用了该ArrayObject::STD_PROP_LIST 标志。
如果传递零,则
现在 ,除了ArrayObject,ArrayIterator, SplDoublyLinkedList和SplObjectStorage还支持__serialize()和__unserialize()机制。这意味着在较旧的PHP版本上创建的序列化有效负载仍然可以反序列化,但是较旧的版本将无法理解由PHP 7.4创建的新有效负载。
58.Tokenizer
token_get_all() 现在将发出一个T_BAD_CHARACTER标记,用于意外字符,而不是在令牌流中留下漏洞。
59.$this的不一 致性更改
虽然$this在PHP中被认为是一个特殊变量,但它缺乏适当的检查,以确保它不被用作变量名称或重新分配。现在,这一点已经得到纠正,以确保$this不能成为用户定义的变量、重新分配到不同的值或全局化。
60.不区分大小写的常量
不区分大小写的常量的声明已被弃用。现在将其TRUE作为第三个参数传递 给
61.正则表达式(与Perl兼容)
该PCRE扩展已经升级到PCRE2,这可能会引起轻微的行为改变(例如,在课堂字符范围现在更严格的解释),并增强现有的正则表达式语法。
当在同一字符串(但可能有不同的偏移量)上重复调用UTF-8模式下的“ u”修饰符)时,将只检查一次UTF-8有效性。
62.
原创文章,转载请注明来自Lenix的博客,地址https://blog.p2hp.com/archives/6918