真的是变懒了,一个月一篇的节凑都很难保证了。php
最近面试他人的过程当中,问了一些关于PHP引用的知识,发现不少同窗对这方面知之甚少,还有不少工做中基本没有使用过。甚至有人告诉我要少用引用,引用会带来一些诡异的问题。我内心默默说,避免诡异的问题是要去理解引用而不是少用引用。今天一块儿来解析解析。面试
先从一个引用的所谓诡异问题开始。假设咱们有这个场景:咱们从数据库中读取了一组订单数据,须要把订单的每条数据单独作些处理。数据库
$orders = [
['orderid' => '123', 'total_fee' => 10, 'name' => 'zhangsan'],
['orderid' => '456', 'total_fee' => 17, 'name' => 'lisi'],
['orderid' => '789', 'total_fee' => 14, 'name' => 'wangwu'],
];
foreach ($orders as &$item) {
// 对订单作了些什么处理
}
// 有了一些其它操做
$result = [];// 须要返回的结果
foreach ($orders as $item) {// 从新映射名字
$result[] = [
'order_id' => $item['orderid'],
'amount' => $item['total_fee'],
];
}
复制代码
上面的程序会输出以下结果:数组
var_dump($result);
array(3) {
[0]=>
array(2) {
["order_id"]=>
string(3) "123"
["total_fee"]=>
int(10)
}
[1]=>
array(2) {
["order_id"]=>
string(3) "456"
["total_fee"]=>
int(17)
}
[2]=>
array(2) {
["order_id"]=>
string(3) "456"
["total_fee"]=>
int(17)
}
}
复制代码
这就是常常遇到的一种所谓的诡异问题,先用引用循环处理数据,后面又用了与引用相同的临时变量继续处理数据。这里就是:$item
。不少同窗说预防这种问题,就要少用引用。这种态度太消极了,引用在不少地方带来了代码书写的简洁,而且针对大数组使用引用可以节省大量的内存。框架
如今咱们来分析下上面问题出现的缘由。先来看引用的定义网站
引用意味着用不一样的名字访问同一个变量内容。spa
那么在这部分代码中code
foreach ($orders as &$item) {
// 对订单作了些什么处理
}
复制代码
$item
最后跟 $orders[2]
指向了同一个变量内容。而且在 foreach
循环完后,$item
并无被销毁,所以在后续若是同名的话,会继续生效。图示以下: cdn
那么再接下来的的另外一个循环中。blog
foreach ($orders as $item) {// 从新映射名字
$result[] = [
'order_id' => $item['orderid'],
'amount' => $item['total_fee'],
];
}
复制代码
每当 $orders
把变量赋值给 $item
的时候,都同时改变了 $orders[2]
的值。所以才会出现上面诡异的状况。我来逐步给你们演示下:
$orders[0]
,$item
指向 orderid=123
的订单,因为 $item
是 $orders[2]
的引用,此时致使 $orders[2]
也指向了 orderid=123
的订单;$orders[1]
, $item
指向 orderid=456
的订单,所以 $orders[2]
也指向了 orderid=456
;$orders[2]
的时候,明显其值已经变成了 orderid=456
的订单。经过上面的分析,我相信你们对引用所谓的诡异有了了解。那么又该如何避免这种状况出现呢?其实很简单,每次使用完引用后,记得 unset
调引用。在后面即可毫无顾忌的继续使用了。具体到本例子就是:
foreach ($orders as &$item) {
// 对订单作了些什么处理
}
unset($item);
// 有了一些其它操做
foreach ($orders as $item) {// 从新映射名字
}
复制代码
前面我说过,引用能够写出简洁的代码。无限级分类的使用即是一个使用场景。好比说咱们有个分类的数据:
$catList = [
'1' => ['id' => 1, 'name' => '颜色', 'parent_id' => 0],
'2' => ['id' => 2, 'name' => '规格', 'parent_id' => 0],
'3' => ['id' => 3, 'name' => '白色', 'parent_id' => 1],
'4' => ['id' => 4, 'name' => '黑色', 'parent_id' => 1],
'5' => ['id' => 5, 'name' => '大', 'parent_id' => 2],
'6' => ['id' => 6, 'name' => '小', 'parent_id' => 2],
'7' => ['id' => 7, 'name' => '黄色', 'parent_id' => 1],
];
复制代码
若是我想获得下面这种形式
$result = [
['id' => 1, 'name' => '颜色', 'children' => [
['id' => 3, 'name' => '白色'],
['id' => 4, 'name' => '黑色'],
['id' => 7, 'name' => '黄色']
]],
['id' => 2, 'name' => '规格', 'children' => [
['id' => 5, 'name' => '大'],
['id' => 6, 'name' => '小']
]]
];
复制代码
若是使用引用,能够很是简单的得出结果。
$treeData = [];// 保存结果
foreach ($catList as $item) {
if (isset($catList[$item['parent_id']]) && ! empty($catList[$item['parent_id']])) {// 确定是子分类
$catList[$item['parent_id']]['children'][] = &$catList[$item['id']];
} else {// 确定是一级分类
$treeData[] = &$catList[$item['id']];
}
}
复制代码
你们能够试试不用引用的方式,把无限级实现出来试试,比较下代码。
年末了。没钱给你们发红包,给你们推荐一家上海的好公司。为你们跳槽助力。
公司网站:https://www.yimishiji.com/
手机网站:https://m.yimishiji.com/
公司目前正在招聘高级PHP工程师,要求:
待遇优厚:五险一金;每日内购零农残、有机食材水果;薪资15k-30k。
公司使用的是PHP7语法,对新技术是保持激进的态度。对于上海的小伙伴或者想去上海的小伙伴,强烈建议去看看。