早上看到了這一篇關於 PHP 技巧的文章:Improving readability using array_filter - murze.be 中文翻譯大概可以說是,用 array_filter
使之更具有可讀性。看到也實際測試了一下,覺得不錯,因此作了一些實驗,也發現一些小坑,所以順便作一下記錄。
以往要在 PHP 的 class 中實作 toArray()
method 我們會寫類似的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Address { private $name; private $city; private $street_line1; private $street_line2; ... public function toArray() { $address = [ 'name' => $this->name, 'city' => $this->city, 'street_line1' => $this->street_line1, ]; if ($this->street_line2 != '') { $address['street_line2'] = $this->street_line2; } ... } }
|
member data 不多的時候,看起來還好。但再多幾個,上面判斷是否為空白的 if 判斷式就會變得非常多,很不好看,也不簡潔。文章內提供的方法就是使用 array_filter
改寫。改寫後的程式碼像這樣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Address { private $name; private $city; private $street_line1; private $street_line2; ...
public function toArray() { return array_filter([ 'name' => $this->name, 'city' => $this->city, 'street_line1' => $this->street_line1, 'street_line2' => $this->street_line2, ... ]); } }
|
整體看起來簡潔多了。使用的就是 array_filter
PHP: array_filter - Manual 的特性。當 array_filter
的第二個參數不帶入 callback function 時,預設的處理方法:「當遇到成員內容為空值或為 null 時,不輸出」。
因此,在使用的時候也要特別小心。舉例來說,假設 street_line1, street_line2 是空字串,則輸出就會只有 name 及 city:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Address { private $name = 'User 1'; private $city = 'Taipei'; private $street_line1 = ''; private $street_line2 = ''; ... public function toArray() { ... } }
$address = new Address(); print_r($address->toArray());
|
而如果直接輸出不存在的 member 也是。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Address { private $name = 'User 1'; private $city = 'Taipei'; ... public function toArray() { ... } }
$address = new Address(); print_r($address->toArray());
|
還有,遇到直接是 null 的時候也是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Address { private $name = 'User 1'; private $city = 'Taipei'; private $street_line1 = null; private $street_line2 = null; ... public function toArray() { ... } }
$address = new Address(); print_r($address->toArray());
|
array_filter
遇到空字串、null、不存在時的這些特性就要特別注意。像是無論如何就算是空字串也要輸出佔一個位置的,就要在額外特別處理了。
看到這樣的運用並且實際作實驗的感覺還蠻有趣的。跟 Improving readability using array_filter - murze.be 作者一樣,第一次發現 array_filter
可以這樣用。