PHP里面最強大的工具,就是數組,它融合了多種數據結構的特點,數組、隊列、棧、哈希表等等,而且容器可以兼容各種類型,任意嵌套,簡直無所不能。圍繞着數組,PHP原生支持了一些列的函數,使得數組在實際編程實踐中,可以有更強的表達能力和更高的編程效率。但是這要求我們用PHP的方式去思考,盡量使用PHP原生的函數解決問題,而不是掌握了一個foreach就一招鮮吃遍天。
本文談論的就是一個數組函數,array_reduce,我在文章的標題中,使用了“降維”這個詞語,因為我聯想到了《三體》里面的維度攻擊,能把三維變二維,實現毀滅性打擊,array_reduce當然不是攻擊用的,但是array_reduce可以幫助我們實現降維,將一維數組“降維”成單一字符串。當然,array_reduce的可以但不僅限於實現這個功能,這取決於運用過程中,程序員對問題的抽象能力。
這里講一種應用場景:從數據庫中按照某種條件,取出一組記錄,然后按照某種規則,將某個特定字段,拼接成一個單一字符串。舉個簡單的例子,比如我們常見的聯表查詢,如果兩張表,位於不同的DB,不同的物理機,甚至是通過開放API拉取回來的數據,那么我們可能沒法使用簡單的聯表查詢,只能分步驟查詢,先查詢一個結果集,將結果集主鍵拼接成IN語句,再到另一個DB去查詢結果集。
1 <?php 2 …… 3 $results1 = fetch_results($db, $sql); 4 $ids = array(); 5 foreach ($results1 as $record) { 6 $ids[] = $record['id']; 7 } 8 9 $sql = "SELECT * FROM tbl_another_table WHERE post_id IN (" .implode(',', $ids) .")"; 10 $results2 = fetch_results($other_db, $sql);
這是非常常見的一種寫法,思路非常自然、直接,也未見什么冗余,但是我覺得,這不是PHP思考問題的方式。PHP的思考方式,是像這樣:
1 <?php 2 function test() { 3 …… 4 $results1 = fetch_results($db, $sql); 5 6 $ids = trim(array_reduce($results1, 'retrive_ids'), ','); 7 8 $sql = "SELECT * FROM tbl_another_table WHERE post_id IN ($ids)"; 9 $results2 = fetch_results($other_db, $sql); 10 …… 11 } 12 13 function retrieve_ids(&$ids, $record) { 14 return $ids . ',' . $record['id']; 15 }
我可能沒法證明,第二種寫法,比第一種寫法要高多少效率,減少多少運行時間,但是我更提倡第二種寫法,因為第二種寫法,是按照PHP的方式在思考問題,提供了更好的語義,更強的表達,retrieve_ids函數還可以復用在類似的場景里。很多情況下,函數里大段的foreach遍歷,都並非為了表達業務本身,而只是為了取得某種中間結果,而PHP提供了工具,幫助我們避免這種局面,而讓自己的代碼更加簡潔易讀。這並非炫耀什么奇技淫巧,這只是PHP自己的正常的方式而已。
