最近從用了2年多的Yii轉到了Yii2,讀了一遍官方檔案以后發現兩個比較有趣的新函式,each()和batch()都是歸于db方面的,看了下原始碼然后寫了點拙見, 先看原始碼,each()和batch()函式都是呼叫BatchQueryResult這個類,唯一的區別是each這個引數,而這個類它實作了Iterator介面,這也就說明了為什么each和batch都要用foreach來呼叫,
簡單說下Iterator,這個介面是PHP預定義的介面,同時它繼承于Traversable預定義介面,這個介面唯一的作用就是檢測一個類是否可以使用 foreach 進行遍歷,
回過來再看BatchQueryResult這個類,主要的兩個可以配置的屬性each和batchSize, each就是用來區別each和batch的屬性,主要表現在next()這個函式上,仔細看了下代碼,其實發現each和batch的區別就是foreach每次取出的資料量,而這個資料量受限于batchSize,默認是100,接下來再看原始碼又會發現each和batch都是一次性取出上限batchSize的資料,區別只不過是foreach遍歷單次輸出的資料each是每次一條,batch每次batchSize條,
具體實作細節看fetchData這個函式,這里本質是填充資料,獲取資料呼叫的是 _dataReadeder->read(), 追蹤函式會發現其實呼叫的是PDO::fetch()函式,限制獲取數量的條件是batchSize,到這里each()和batch()其實是一樣的,具體這兩個函式的區別要看next()函式:
理解這里可以先看下官方檔案關于foreach呼叫時的內部實作(https://www.php.net/manual/zh/class.iterator.php),這邊可以看出本質上each()和batch()每次都取出batchSize個資料,但是區別是each()在遍歷時候每次只取出一個,batch()直接回傳batchSize個資料,所以如果對記憶體有要求不管each()還是batch()都要按需限制下batchSize引數,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/10144.html
標籤:PHP
