foreach 循环中的变量引用
foreach中的变量引用可以用来更改数组中的元素,例如
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr foreach后的值为(2, 4, 6, 8)
但是变量的引用也会导致一些意想不到的bug,比如下面的例子
$array = [1, 2, 3];
foreach ($array as &$value) {} // 通过引用的方式, $value是数组$array元素的引用
echo implode(',', $array), "\n";
foreach ($array as $value) {} // 通过赋值的方式
echo implode(',', $array), "\n";
// 结果是
1,2,3
1,2,2
后面再循环$array的结果却不是1,2,3而是1,2,2 这是因为在每一次循环过后,$array中的元素都会赋给$value, 因为$value是引用的方式,在循环结束后,$value仍然引用数组的最后一个元素,也就是$array[2], 这时候在第二次foreach循环的时候,因为$value仍然是引用$array[2], 当把数组中的每一个元素赋给$value的时候,$array[2]的值也跟着改变,在第二次foreach的时候
- 把$array[0]赋值给$value,因为$value是引用$array[2], 所以这个时候$array[2]的值也变为1
- 把$array[1]赋值给$value的时候,因为$value是引用$array[2], 所以$array[2]的值变为2
- 这个时候需要把$array[2]的值赋给$value, 因为$array[2]=2,所以$value的值也是2 这样,foreach之后,$array的元素就变为[1, 2, 2]了。 所以在foreach修改元素值的时候,为了避免引入bug,就需要删除引用
$arr = array(1, 2, 3);
foreach ($arr as &$value) {
$value = $value * 2;
}
unset($value); // 删除$value和$arr中最后一个元素的引用
isset的误区
isset检查变量是否设置的时候并不可靠
$arr = [];
$arr['name'] = null;
var_dump(isset($arr['name'])); // result is false
// 如果要检测变量是否存在并不为空
if ($arr['name']) {
// key存在并不为空
} else {
}
isset在变量的值是null的时候依然会返回false, 所以如果要检测变量存在并且不为空要使用if来判断,最主要的是取决于你期望获得的结果是什么。
$_POST误区
$_POST超级全局变量并不总是能获得POST方法提交来的数据
$.ajax({
url: 'http://my.site/some/path',
method: 'post',
data: JSON.stringify({a: 'a', b: 'b'}),
contentType: 'application/json'
});
上面这段通过ajax请求并且请求方法是post,不过它的contentType是application/json
,这种方式在当前开发中很常见,
但是打印$_POST输出的却是空数组,这是为什么呢?
这是因为在POST方法请求PHP执行时,PHP只能处理content type是application/x-www-form-urlencode
或者multipart/form-data
格式的,
所以上面这种application/json
Content Type不在$_POST变量中,那么我们该怎么处理这种格式呢
// 通过这种方式来获得content type是`application/json`的数据
$data = json_decode(file_get_contents('php://input'), true);
参考
https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make