摘要:最近面試他人的過(guò)程中,問(wèn)了一些關(guān)于引用的知識(shí),發(fā)現(xiàn)很多同學(xué)對(duì)這方面知之甚少,還有很多工作中基本沒(méi)有使用過(guò)。沒(méi)錢(qián)給大家發(fā)紅包,給大家推薦一家上海的好公司。對(duì)于上海的小伙伴或者想去上海的小伙伴,強(qiáng)烈建議去看看。
真的是變懶了,一個(gè)月一篇的節(jié)湊都很難保證了。
最近面試他人的過(guò)程中,問(wèn)了一些關(guān)于PHP引用的知識(shí),發(fā)現(xiàn)很多同學(xué)對(duì)這方面知之甚少,還有很多工作中基本沒(méi)有使用過(guò)。甚至有人告訴我要少用引用,引用會(huì)帶來(lái)一些詭異的問(wèn)題。我心里默默說(shuō),避免詭異的問(wèn)題是要去理解引用而不是少用引用。今天一起來(lái)解析解析。
場(chǎng)景假設(shè)先從一個(gè)引用的所謂詭異問(wèn)題開(kāi)始。假設(shè)我們有這個(gè)場(chǎng)景:我們從數(shù)據(jù)庫(kù)中讀取了一組訂單數(shù)據(jù),需要把訂單的每條數(shù)據(jù)多帶帶做些處理。
$list = [ ["orderid" => "123", "total_fee" => 10, "name" => "zhangsan"], ["orderid" => "456", "total_fee" => 17, "name" => "lisi"], ["orderid" => "789", "total_fee" => 14, "name" => "wangwu"], ]; foreach ($list as &$item) { // 對(duì)訂單做了些什么處理 } // 有了一些其它操作 $result = [];// 需要返回的結(jié)果 foreach ($list as $item) {// 重新映射名字 $result[] = [ "order_id" => $item["orderid"], "amount" => $item["total_fee"], ]; }
上面的程序會(huì)輸出如下結(jié)果:
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) } }
這就是經(jīng)常遇到的一種所謂的詭異問(wèn)題,先用引用循環(huán)處理數(shù)據(jù),后面又用了與引用相同的臨時(shí)變量繼續(xù)處理數(shù)據(jù)。這里就是:$item。很多同學(xué)說(shuō)預(yù)防這種問(wèn)題,就要少用引用。這種態(tài)度太消極了,引用在很多地方帶來(lái)了代碼書(shū)寫(xiě)的簡(jiǎn)潔,并且針對(duì)大數(shù)組使用引用能夠節(jié)省大量的內(nèi)存。
詭異問(wèn)題解析現(xiàn)在我們來(lái)分析下上面問(wèn)題出現(xiàn)的原因。先來(lái)看引用的定義
引用意味著用不同的名字訪問(wèn)同一個(gè)變量?jī)?nèi)容。
那么在這部分代碼中
foreach ($list as &$item) { // 對(duì)訂單做了些什么處理 }
$item 最后跟 $list[2] 指向了同一個(gè)變量?jī)?nèi)容。并且在 foreach 循環(huán)完后,$item 并沒(méi)有被銷(xiāo)毀,因此在后續(xù)如果同名的話(huà),會(huì)繼續(xù)生效。圖示如下:
那么再接下來(lái)的的另一個(gè)循環(huán)中。
foreach ($list as $item) {// 重新映射名字 $result[] = [ "order_id" => $item["orderid"], "amount" => $item["total_fee"], ]; }
每當(dāng) $list 把變量賦值給 $item 的時(shí)候,都同時(shí)改變了 $list[2] 的值。因此才會(huì)出現(xiàn)上面詭異的情況。我來(lái)逐步給大家演示下:
第一次循環(huán) $list[0],$item 指向 orderid=123 的訂單,由于 $item 是 $list[2] 的引用,此時(shí)導(dǎo)致 $orders[2] 也指向了 orderid=123 的訂單;
第二次循環(huán) $list[1], $item 指向 orderid=456 的訂單,因此 $list[2] 也指向了 orderid=456;
第三次循環(huán) $list[2]的時(shí)候,明顯其值已經(jīng)變成了 orderid=456 的訂單。
通過(guò)上面的分析,我相信大家對(duì)引用所謂的詭異有了了解。那么又該如何避免這種情況出現(xiàn)呢?其實(shí)很簡(jiǎn)單,每次使用完引用后,記得 unset 調(diào)引用。在后面便可毫無(wú)顧忌的繼續(xù)使用了。具體到本例子就是:
foreach ($list as &$item) { // 對(duì)訂單做了些什么處理 } unset($item); // 有了一些其它操作 foreach ($list as $item) {// 重新映射名字 }引用的妙用
前面我說(shuō)過(guò),引用可以寫(xiě)出簡(jiǎn)潔的代碼。無(wú)限級(jí)分類(lèi)的使用便是一個(gè)使用場(chǎng)景。比如說(shuō)我們有個(gè)分類(lèi)的數(shù)據(jù):
$catList = [ "1" => ["id" => 1, "name" => "顏色", "parent_id" => 0], "2" => ["id" => 2, "name" => "規(guī)格", "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" => "規(guī)格", "children" => [ ["id" => 5, "name" => "大"], ["id" => 6, "name" => "小"] ]] ];
如果使用引用,可以非常簡(jiǎn)單的得出結(jié)果。
$treeData = [];// 保存結(jié)果 foreach ($catList as $item) { if (isset($catList[$item["parent_id"]]) && ! empty($catList[$item["parent_id"]])) {// 肯定是子分類(lèi) $catList[$item["parent_id"]]["children"][] = &$catList[$item["id"]]; } else {// 肯定是一級(jí)分類(lèi) $treeData[] = &$catList[$item["id"]]; } }
大家可以試試不用引用的方式,把無(wú)限級(jí)實(shí)現(xiàn)出來(lái)試試,比較下代碼。
年底了。沒(méi)錢(qián)給大家發(fā)紅包,給大家推薦一家上海的好公司。為大家跳槽助力。
公司網(wǎng)站:https://www.yimishiji.com/
手機(jī)網(wǎng)站:https://m.yimishiji.com/
公司目前正在招聘高級(jí)PHP工程師,要求:
2-5年的PHP開(kāi)發(fā)經(jīng)驗(yàn);
本科學(xué)歷;
至少熟悉Laravel、Yii2框架中的一種;
有電商、生鮮相關(guān)的經(jīng)驗(yàn)加分;
有博客、GitHub的加分。
待遇優(yōu)厚:五險(xiǎn)一金;每日內(nèi)購(gòu)零農(nóng)殘、有機(jī)食材水果;薪資15k-30k。
公司使用的是PHP7語(yǔ)法,對(duì)新技術(shù)是保持激進(jìn)的態(tài)度。對(duì)于上海的小伙伴或者想去上海的小伙伴,強(qiáng)烈建議去看看。
公司地址:上海市長(zhǎng)寧區(qū)天山西路789號(hào)中山國(guó)際廣場(chǎng)B座一米市集
CTO郵箱:[email protected]
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26230.html
摘要:已經(jīng)發(fā)布如承諾我也要開(kāi)始這個(gè)系列的文章的編寫(xiě)今天我想先和大家聊聊的變化在講變化的之前我們先來(lái)看看在下面是什么樣子回顧在的時(shí)候的定義如下對(duì)內(nèi)核有了解的同學(xué)應(yīng)該對(duì)這個(gè)結(jié)構(gòu)比較熟悉因?yàn)榭梢员硎疽磺兄械臄?shù)據(jù)類(lèi)型所以它包含了一個(gè)字段表示這個(gè)存儲(chǔ)的是什 PHP7已經(jīng)發(fā)布, 如承諾, 我也要開(kāi)始這個(gè)系列的文章的編寫(xiě), 今天我想先和大家聊聊zval的變化. 在講zval變化的之前我們先來(lái)看看zval在...
摘要:本文主要是針對(duì),的話(huà)可以移步到慶哥的博客看,還有就是小菜我讀的是內(nèi)核剖析這本書(shū)。接下來(lái)我會(huì)使用到來(lái)調(diào)試源碼本文有參照博客中的部分內(nèi)容以及代碼。 前言 工作+實(shí)習(xí)快一年了,搞php后端開(kāi)發(fā),一直很迷茫怎么提高自己,就先從php源碼開(kāi)始吧,本人比較菜,本文章寫(xiě)的比較趕時(shí)間,所以有什么錯(cuò)誤或者漏掉的地方,望各位大神指正,多交流才能成長(zhǎng)嘛,嘿嘿。本文主要是針對(duì)php7,php5的話(huà)可以移步到慶...
摘要:垃圾回收器追蹤所有正在使用的對(duì)象,將無(wú)用對(duì)象標(biāo)記為垃圾。自動(dòng)化指針內(nèi)存回收自動(dòng)化的最好方式之一是使用鉤子函數(shù)。它們可能因?yàn)槎喾N原因發(fā)生,但是這種垃圾回收器是最主流的一種。 原文出處:What Is Garbage Collection? 一眼就應(yīng)該從名稱(chēng)看出垃圾回收機(jī)制的含義-查找垃圾,然后丟棄。事實(shí)正好相反。垃圾回收器追蹤所有正在使用的對(duì)象,將無(wú)用對(duì)象標(biāo)記為垃圾。請(qǐng)留意,我們開(kāi)始研究...
摘要:一概述集合是引入的新的內(nèi)置對(duì)象類(lèi)型,其特點(diǎn)同數(shù)學(xué)意義的集合,即集合內(nèi)所有元素不重復(fù)元素唯一。數(shù)組集合對(duì)比數(shù)組和集合,數(shù)組可以加入重復(fù)數(shù)據(jù),而集合的所有元素是唯一的不允許重復(fù)。因此,適合臨時(shí)存放一組對(duì)象,以及存放跟對(duì)象綁定的信息。 本文同步帶你入門(mén) 帶你入門(mén) JavaScript ES6 (五) 集合,轉(zhuǎn)載請(qǐng)注明出處。 前面我們學(xué)習(xí)了: for of 變量和擴(kuò)展語(yǔ)法 塊作用域變量和解構(gòu)...
摘要:運(yùn)算符的優(yōu)先級(jí),是明顯高于,因此先執(zhí)行再執(zhí)行。這里會(huì)非常有趣的將轉(zhuǎn)換成一個(gè)數(shù)字而且默認(rèn)去掉了前面的也就是很顯然上面的問(wèn)題已經(jīng)說(shuō)過(guò)了數(shù)字和字符串類(lèi)型不一致。 showImg(https://segmentfault.com/img/bVvhhO); 本文翻譯自:https://www.toptal.com/php/interview-questions ,文章所羅列的問(wèn)題雖然看似簡(jiǎn)單,但...
閱讀 2302·2021-10-09 09:41
閱讀 1757·2019-08-30 15:53
閱讀 1002·2019-08-30 15:52
閱讀 3453·2019-08-30 11:26
閱讀 780·2019-08-29 16:09
閱讀 3438·2019-08-29 13:25
閱讀 2275·2019-08-26 16:45
閱讀 1943·2019-08-26 11:51