$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
现在迭代会正确的添加了元素。如上代码输出是 "int(0) int(1)",而以前只是 "int(0)"。
对普通(不可遍历的)对象按值或按引用迭代的行为类似于对数组进行按引用迭代。这符合以前的行为,除了如上一点所述的更精确的位置管理的改进。
对可遍历对象的迭代行为保持不变。
相关 RFC: https://wiki.php.net/rfc/php7_foreach
参数处理的变化
不能定义两个同名的函数参数。例如,下面的方法将会触发编译时错误:
复制代码 代码如下:
public function foo($a, $b, $unused, $unused) {
// ...
}
如上的代码应该修改使用不同的参数名,如:
复制代码 代码如下:
public function foo($a, $b, $unused1, $unused2) {
// ...
}
func_get_arg() 和 func_get_args() 函数不再返回传递给参数的原始值,而是返回其当前值(也许会被修改)。例如:
复制代码 代码如下:
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
将会打印 "2" 而不是 "1"。代码应该改成仅在调用 func_get_arg(s) 后进行修改操作。
复制代码 代码如下:
function foo($x) {
var_dump(func_get_arg(0));
$x++;
}
或者应该避免修改参数:
复制代码 代码如下:
function foo($x) {
$newX = $x + 1;
var_dump(func_get_arg(0));
}
类似的,异常回溯也不再显示传递给函数的原始值,而是修改后的值。例如:
复制代码 代码如下:
function foo($x) {
$x = 42;
throw new Exception;
}
foo("string");
现在堆栈跟踪的结果是:
复制代码 代码如下:
Stack trace:
#0 file.php(4): foo(42)
#1 {main}
而以前是:
复制代码 代码如下:
Stack trace:
#0 file.php(4): foo('string')
#1 {main}
这并不会影响到你的代码的运行时行为,值得注意的是在调试时会有所不同。
同样的限制也会影响到 debug_backtrace() 及其它检查函数参数的函数。
相关 RFC: https://wiki.php.net/phpng
整数处理的变化
无效的八进制表示(包含大于7的数字)现在会产生编译错误。例如,下列代码不再有效:
$i = 0781; // 8 不是一个有效的八进制数字!
以前,无效的数字(以及无效数字后的任何数字)会简单的忽略。以前如上 $i 的值是 7,因为后两位数字会被悄悄丢弃。
二进制以负数镜像位移现在会抛出一个算术错误:
复制代码 代码如下:
var_dump(1 >> -1);
// ArithmeticError: 以负数进行位移
向左位移的位数超出了整型宽度时,结果总是 0。
复制代码 代码如下:
var_dump(1 << 64); // int(0)
以前上述代码的结果依赖于所用的 CPU 架构。例如,在 x86(包括 x86-64) 上结果是 int(1),因为其位移操作数在范围内。
类似的,向右位移的位数超出了整型宽度时,其结果总是 0 或 -1 (依赖于符号):
复制代码 代码如下:
var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)
相关 RFC: https://wiki.php.net/rfc/integer_semantics
字符串处理的变化
包含十六进制数字的字符串不会再被当做数字,也不会被特殊处理。参见例子中的新行为:
复制代码 代码如下:
var_dump("0x123" == "291"); // bool(false) (以前是 true)
var_dump(is_numeric("0x123")); // bool(false) (以前是 true)
var_dump("0xe" + "0x1"); // int(0) (以前是 16)
var_dump(substr("foo", "0x1")); // string(3) "foo" (以前是 "oo")
// 注意:遇到了一个非正常格式的数字
filter_var() 可以用来检查一个字符串是否包含了十六进制数字,或这个字符串是否能转换为整数:
$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)
由于给双引号字符串和 HERE 文档增加了 Unicode 码点转义格式(Unicode Codepoint Escape Syntax), 所以带有无效序列的 "\u{" 现在会造成错误:
$str = "\u{xyz}"; // 致命错误:无效的 UTF-8 码点转义序列
要避免这种情况,需要转义开头的反斜杠:
$str = "\\u{xyz}"; // 正确
不过,不跟随 { 的 "\u" 不受影响。如下代码不会生成错误,和前面的一样工作:
$str = "\u202e"; // 正确
相关 RFC: