PHP7.0版本备注(2)


$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:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f4b4929b666297575ae08dbee03f0191.html