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