作者: Laruence
本文地址: http://www.laruence.com/2011/11/28/2317.html
在PHP5.4中, 对字符串多级取值(offset), 做了一个一致性改进. 比如对于下面的例子:
<?php
$str = "laruence";
echo $str[0][0][0][0];
?>
在PHP5.4之前, 上面的代码会导致一个Fatal error:
PHP Fatal error: Cannot use string offset as an array
这个错误其实很莫名, 因为$str[0], 是’l', 也是一个字符串, 那么按理来说, $str[0][0]还应该是’l', 于是在PHP5.4中, 对这个不一致性做了改进. 但是也带来了一个需要注意的变化.
对于上面的列子, 在PHP5.4将输出”l”.
但是, 这样就带来一个明显的变化:
<?php
$arr = array(
"name" => "laruence", //如果这个值有可能是数组,或者字符串.
);
if (isset($arr["name"]["foo"]["non-exists"])) {
echo "set";
}
注意上面的代码, 因为对arra的数组的元素的值类型不确定(有可能是数组,也有可能是字符串), 那么在PHP5.4之前, 上面的代码, 错误的表现出了正确: 不管数组还是字符串, 都可以返回看似正确的没有isset.
而从5.4开始, 将会输出”set”.
这是为什么呢?
因为类型转换, 当$arr["name"]是字符串的时候, 对它做offset取值, 都会把键值转换成interge, 所以, “foo”和”non-exists”都会转换成0.
也就是, $arr["name"][0][0], 所以isset为真.
当然, 如果你之前一直是使用array_key_exists的话, 这个变化倒也影响不到你.
这个变化需要以后在你不能保证一个数组中值的类型的(数组,字符串)的时候, 如果做isset操作, 需要增加一些额外的is_array判断...
不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.
=============================update=========================================
在之前, 我曾经介绍过, 在PHP5.4中, PHP5.4中一个需要注意的变化(Chained string offsets) , 后续因为大多数人都表示这个变化很敏感, 容易成为坑.. 于是, 我们现在对此做了一些改进.
具体的改变是, 对于一个变量$a, 如果$a是一个字符串, 那么, 对于非数字型索引, 比如$a["foo"], 在isset的时候将返回false, empty返回true, 但是为了兼容已有的代码, 当你获取这个值的时候, 还是会返回$a[0], 不过会额外抛出一个警告信息. 比如:
<?php
$a = "laruence";
var_dump($a["foo"]) ; //PHP Warning: Illegal string offset 'foo'
//output string(1) "l"
var_dump(isset($a["foo"]));
//false
var_dump(empty($a["foo"]));
//true
而对于键值是bool, double, null的情况, 将会和以前保持一致, 不过会抛出一个Notice信息.
<?php
$a = "bar";
echo $a[TRUE]; //PHP Notice: String offset cast occured
//output a
而对于数字型的字符串索引, 比如”1″, “12″等, 和以前保持一致.
更多更新信息, 请关注: Changelog