补充*不向后兼容的变更
- E_STRICT 警告级别变更
- 关于list()处理方式的变更
- 常用的方式
- list() 不再以反向的顺序来进行赋值
- 空的list()赋值支持已经被移除
- list() string 不再能解开
- 当引用分配时自动创建元素的数组排序已更改
- global只接受简单变量
- 函数参数附近的括号不再影响行为
- foreach的变化
- foreach不再改变内部数组指针
- foreach通过值遍历时,操作的值为数组的副本
- foreach通过引用遍历时,有更好的迭代特性
- string处理上的调整
- 十六进制字符串不再被认为是数字
- \u{可能引起错误
- 被移除的函数(Removed functions)
- 所有的 ereg* 函数
- 所有 ext/mysql 函数
- set_magic_quotes_runtime()
- set_socket_blocking()
- dl() in PHP-FPM
- GD Type1 functions
- 被移除掉的 INI 配置指令
- 被移除的功能
- 其他不向后兼容的变更
- new 操作符创建的对象不能以引用方式赋值给变量
- 无效的类、接口以及 trait 命名
- 移除了 ASP 和 script PHP 标签
- 从不匹配的上下文发起调用
- yield 变更为右联接运算符
- 函数定义不可以包含多个同名参数
- Switch 语句不可以包含多个 default 块
- 在函数中检视参数值会返回当前的值
- $HTTP_RAW_POST_DATA被移除
- INI 文件中#注释格式被移除
- JSON 扩展已经被 JSOND 取代
- 在数值溢出的时候,内部函数将会失败
- 自定义会话处理器的返回值修复
- 相等的元素在排序时的顺序问题
原有的
E_STRICT
警告都被迁移到其他级别。E_STRICT
常量会被保留,所以调用error_reporting(E_ALL|E_STRICT)不会引发错误.举例(以静态方式调用实例方法):
<?php
error_reporting(E_ALL|E_STRICT);
class mycls{
function func()
{
echo "none static";
}
}
mycls::func();
php7 中则会印发新的
E_DEPRECATED 级别的错误
eprecated: Non-static method mycls::func() should not be called statically in xxxx
场景 | 新的级别/行为 |
将资源类型的变量用作键来进行索引 | E_NOTICE |
抽象静态方法 | 不再警告,会引发错误 |
重复定义构造器函数 | 不再警告,会引发错误 |
在继承的时候,方法签名不匹配 | E_WARNING |
在两个 trait 中包含相同的(兼容的)属性 | 不再警告,会引发错误 |
以非静态调用的方式访问静态属性 | E_NOTICE |
变量应该以引用的方式赋值 | E_NOTICE |
变量应该以引用的方式传递(到函数参数中) | E_NOTICE |
以静态方式调用实例方法 | E_DEPRECATED |
<?php
$str = "China|Chinese";
list($country, $language) = explode('|', $str);
echo 'country:' . $country;
echo 'language:' . $language;
官方说明:
PHP7 现在会按照变量定义的顺序来给他们进行赋值,而非反过来的顺序。 通常来说,这只会影响list() 与数组的[]操作符一起使用的案例,如下所示:
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>
Output of the above example in PHP 5:
array(3) {
[0]=>
int(3)
[1]=>
int(2)
[2]=>
int(1)
}
Output of the above example in PHP 7:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>
如下代码,在php 5.x 当中顺利运行,并输出相应的 a b 值 ,但是在php7 中不会输出 如下:
<?php
$str = 'ab';
list($a, $b) = $str;
echo $a;
echo $b;
list() 不再能解开字符串(string)变量。 你可以使用str_split()来代替它,如下代码:
str_split() 函数把字符串分割到数组中。 第二个可选参数支持规定每个数组元素的长度。默认是 1。
<?php
$str = 'ab';
list($a, $b) = str_split($str);
echo $a;
echo $b;
数组中的元素的顺序已更改,这些元素在引用引用赋值时自动创建。例如:
<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>
Output of the above example in PHP 5:
array(2) {
["b"]=>
&int(1)
["a"]=>
&int(1)
}
Output of the above example in PHP 7:
array(2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
可变变量不再能够与 global 关键字一起使用。 如果在PHP7 中需要的话可以使用圆括号来模拟之前的行为。
<?php
function f() {
// Valid in PHP 5 only.
global $$foo->bar;
// Valid in PHP 5 and 7.
global ${$foo->bar};
}
?>
在PHP 7中(官方标注为php5,经过测试php5中无报错,报错在php7中,故作修改),当函数参数通过引用传递时,围绕函数参数使用冗余括号可以保持严格的标准警告。警告将永远发出。
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
function getArray() {
return [1, 2, 3];
}
function squareArray(array &$a) {
foreach ($a as &$v) {
$v **= 2;
}
}
// Generates a warning in PHP 7.
squareArray((getArray()));
以上栗子会报错:
Notice: Only variables should be passed by reference in xxxxx
foreach发生了细微的变化,控制结构, 主要围绕阵列的内部数组指针和迭代处理的修改。
在PHP7之前,当数组通过foreach迭代时,数组指针会移动。现在开始,不再如此,见下面代码:
<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
?>
Output of the above example in PHP 5:
int(1)
int(2)
bool(false)
Output of the above example in PHP 7:
int(0)
int(0)
int(0)
当默认使用通过值遍历数组时,foreach实际操作的是数组的迭代副本,而非数组本身。这就意味着,foreach 中的操作不会修改原数组的值。
当使用引用遍历数组时,现在foreach在迭代中能更好的跟踪变化。例如,在迭代中添加一个迭代值到数组中,参考下面的代码:
<?php
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
?>
Output of the above example in PHP 5:
int(0)
Output of the above example in PHP 7:
int(0)
int(1)
含十六进制字符串不再被认为是数字(也就是十六进制的字符串不会转成十进制数字进行比较,而是做一个字符串)。例如:
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>
Output of the above example in PHP 5:
bool(true)
bool(true)
int(15)
string(2) "oo"
Output of the above example in PHP 7:
bool(false)
bool(false)
int(0)
Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"
解决办法:
filter_var() 函数可以用于检查一个 string 是否含有十六进制数字,并将其转换为integer:
<?php
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>
此外,已废弃的mcrypt_ecb(),mcrypt_cbc(),mcrypt_cfb()和mcrypt_ofb()函数已被移除,请配合恰当的
MCRYPT_MODE_*
常量来使用mcrypt_decrypt()进行代替。set_magic_quotes_runtime(), 和它的别名magic_quotes_runtime()已被移除. 它们在PHP 5.3.0中已经被废弃,并且 在in PHP 5.4.0也由于魔术引号的废弃而失去功能。
PostScript Type1字体的支持已经从GD扩展删除,导致以下功能的去除:
推荐使用 TrueType 字体和相关的函数作为替代。
以下 INI 配置指令已经被移除,同时移除的还有其对应的功能
xsl.security_prefs
<?php
class C {}
$c =& new C;
?>
Output of the above example in PHP 5:
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3
Output of the above example in PHP 7:
Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3
不能以下列名字来命名类、接口以及 trait:
此外,也不要使用下列的名字来命名类、接口以及 trait。虽然在 PHP 7.0 中, 这并不会引发错误, 但是这些名字是保留给将来使用的。
使用类似 ASP 的标签,以及 script 标签来区分 PHP 代码的方式被移除。 受到影响的标签有:
被移除的 ASP 和 script 标签
开标签 | 闭标签 |
<% | %> |
<%= | %> |
<script language="php"> | </script> |
<?php
class A {
public function test() { var_dump($this); }
}
// 注意:并没有从类 A 继承
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
?>
Output of the above example in PHP 5.6:
Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}
Output of the above example in PHP 7:
Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8
Notice: Undefined variable: this in /tmp/test.php on line 3
NULL
在使用 yield 关键字的时候,不再需要括号, 并且它变更为右联接操作符,其运算符优先级介于 print 和 => 之间。 这可能导致现有代码的行为发生改变:
<?php
echo yield -1;
// 在之前版本中会被解释为:
echo (yield) - 1;
// 现在,它将被解释为:
echo yield (-1);
yield $foo or die;
// 在之前版本中会被解释为:
yield ($foo or die);
// 现在,它将被解释为:
(yield $foo) or die;
?>
可以通过使用括号来消除歧义。
在函数定义中,不可以包含两个或多个同名的参数。 例如,下面代码中的函数定义会触发
E_COMPILE_ERROR
错误:<?php
function foo($a, $b, $unused, $unused) {
//
}
?>
在 switch 语句中,两个或者多个 default 块的代码已经不再被支持。 例如,下面代码中的 switch 语句会触发
E_COMPILE_ERROR
错误:<?php
switch (1) {
default:
break;
default:
break;
}
?>
当在函数代码中使用 func_get_arg() 或 func_get_args() 函数来检视参数值, 或者使用 debug_backtrace() 函数查看回溯跟踪, 以及在异常回溯中所报告的参数值是指参数当前的值(有可能是已经被函数内的代码改变过的值), 而不再是参数被传入函数时候的原始值了。
<?php
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);?>
Output of the above example in PHP 5:
1
Output of the above example in PHP 7:
2
JSON 扩展已经被 JSOND 扩展取代。 对于数值的处理,有以下两点需要注意的: 第一,数值不能以点号(.)结束 (例如,数值34.必须写作34.0或34)。 第二,如果使用科学计数法表示数值,e前面必须不是点号(.) (例如,3.e3必须写作3.0e3或3e3)。 另外,空字符串不再被视作有效的 JSON 字符串。
将浮点数转换为整数的时候,如果浮点数值太大,导致无法以整数表达的情况下, 在之前的版本中,内部函数会直接将整数截断,并不会引发错误。 在 PHP 7.0 中,如果发生这种情况,会引发 E_WARNING 错误,并且返回
NULL
。在自定义会话处理器中,如果函数的返回值不是
FALSE
,也不是-1, 会引发致命错误。现在,如 果这些函数的返回值不是布尔值,也不是-1或者0,函数调用结果将被视为失败,并且引发 E_WARNING 错误。由于内部排序算法进行了提升, 可能会导致对比时被视为相等的多个元素之间的顺序不稳定。
在对比时被视为相等的多个元素之间的排序顺序是不可信赖的,即使是相等的两个元素, 他们的位置也可能被排序算法所改变。
Last modified 4yr ago