我是 Laravel 開發員,不是 PHP 開發員

Shuyi發表於2019-01-22

國外DISS PHP 的人很多很多,但是說Laravel壞話的沒有。我發現很多Laravel 開發者不會想去 php.net 找答案,因為裡面你所能看到的大部分函式, Laravel 有一個(或者多個)對應包裹 (Wrapper) 或者 函式。 做Laravel多了,甚至有種沒有在寫PHP的感覺。 我儘量不用PHP函式,理由如下:

  1. 保持程式碼標準。比如說函式應該是小駝峰,但是 PHP的函式都是蛇行 (snake_case)。現在業界的標準是,所有函式都應該是小駝峰 (camelCase),所有類都應該是大駝峰(CamelCase) , 所有常量 都應該是全大寫 。 Laravel 本身的函式都是跟這個標準的, ( arr_search, str_replace 那類是例外,我基本上也不用他們)
  2. 流式介面 ( Fluent Interface) 。Laravel很多時候是推薦這種程式碼格式的,我們很經常這麼寫:
    $user = App\User::where('name', 'Test')
                            ->whereNull('verification_date');

    如果這些函式PHP有的話,你就要可能這麼寫:

    $userObject = new App\User();
    $user = user_where_null(user_where('name', 'Test'), 'verification_date');                           

    你需要的函式越多,括號也越多。所以我是傾向於流式介面的,乾淨,高階大氣上檔次。但是Laravel不是萬能的, 有些函式也是沒有的. (下面有例子)

我昨天看到了 LHao 大大的 這個: 部落格:每日五個 PHP 函式記憶 , 啟發了我,把那些 PHP 函式轉換為 Laravel 函式, 就先翻譯五個吧:

  • array_combine --- 建立一個陣列,用一個陣列的值作為其鍵名,另一個陣列的值作為其值 ,
// php 版本

$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);

print_r($c); // 輸出:['green' => 'avocado', 'red' => 'apple', 'yellow' => 'banana']

// Laravel 版本
$a = collect(['green', 'red', 'yellow']);
$b = ['avocado', 'apple', 'banana'];
$a->combine($b)
    ->dump();
 //輸出: 
Collection {#1812 ▼
  #items: array:3 [▼
    "green" => "avocado"
    "red" => "apple"
    "yellow" => "banana"
  ]
}
  • array_count_values --- 統計陣列中所有的值, 沒有 Laravel 版本
// 說明:array_count_values ( array $array ) : array

$array = array(1, "hello", 1, "world", "hello");

print_r(array_count_values($array)); // 輸出:[1 => 2, "hello" => 2, "world" => 1]
  • array_diff_assoc --- 帶索引檢查計算陣列的差集
// 說明:array_diff_assoc ( array $array1 , array $array2 [, array $... ] ) : array

$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");

$result = array_diff_assoc($array1, $array2);

print_r($result); // 輸出:["b" => "brown", "c" => "blue", 0 => "red"]
// 大家可以發現這裡 red 有輸出,為啥呢,因為第二個陣列中 red 的 key 為 1。與陣列一中的 key 為 0,不一致,所以有輸出。

// Laravel

        $array1 = collect([
            "a" => "green",
            "b" => "brown",
            "c" => "blue", "red"
        ]);
        $array2 = [
            "a" => "green",
            "yellow", "red"
        ];

        return $array1->diffAssoc($array2);

// Result 
{
"0": "red",
"b": "brown",
"c": "blue"
}
  • array_diff_key --- 使用鍵名比較計算陣列的差集
// 說明:array_diff_key ( array $array1 , array $array2 [, array $... ] ) : array

$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_diff_key($array1, $array2)); // 輸出:['red' => 2, 'purple' => 4]

//laravel 
        $array1 = collect([
            'blue' => 1,
            'red' => 2,
            'green' => 3,
            'purple' => 4]
        );
        $array2 = [
            'green' => 5,
            'blue' => 6,
            'yellow' => 7,
            'cyan' => 8
        ];

        return $array1->diffKeys($array2);

// result

{
"red": 2,
"purple": 4
}
  • array_diff_uassoc --- 用使用者提供的回撥函式做索引檢查來計算陣列的差集
// 說明:array_diff_uassoc ( array $array1 , array $array2 [, array $... ], callable $key_compare_func ) : array

function key_compare_func($a, $b)
{
    if ($a === $b) {
        return 0;
    }
    return ($a > $b)? 1:-1;
}

$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");

$result = array_diff_uassoc($array1, $array2, "key_compare_func");

print_r($result); // 輸出:["b" => "brown", "c" => "blue", 0 => "red"]
// Laravel

        $array1 = collect([
            "a" => "green",
            "b" => "brown",
            "c" => "blue",
            "red"
        ]);

        $array2 = [
            "a" => "green",
            "yellow",
            "red"
        ];

        return $array1->diffAssocUsing($array2, function ($a, $b) {
            if ($a === $b) {
                return 0;
            }
            return $a > $b
                ? 1
                : -1;
        });
// result
{
"0": "red",
"b": "brown",
"c": "blue"
}

如果需要多過一個函式的時候, Collect 和 流式介面 的優勢就顯現出來了, 栗子:

     $array1 = collect([
            'blue' => 1,
            'red' => 2,
            'green' => 3,
            'purple' => 4]
        );
        $array2 = [
            'green' => 5,
            'blue' => 6,
            'yellow' => 7,
            'cyan' => 8
        ];

        return $array1->diffKeys($array2)
            ->transform(function ($item, $key) {
                return [
                    'key'        => $key,
                    'difference' => $item,
                ];
            })
            ->values()
            ->all();

//結果

[
    {
    "key": "red",
    "difference": 2
    },
    {
    "key": "purple",
    "difference": 4
    }
]

上面的例子, 首先用 Key 找到兩個 Array 的差別,然後將結果變形 (變形或者 Transform 會保留原本的Key, 只變形值),剔除原本的 Key , 然後整合成全新的 Array 。 可以看得出來,很清楚,很容易修改程式碼, 如果你要是用原本的PHP函式,你就得去追括號了,很多括號 。。。。 額,我殘念了。

當然 Laravel Collection 也不是萬能的,比如說上面那個 array_count_values 我就沒找到好的代替方法,所以在這種情況下,還是乖乖用 PHP 自帶功能吧。

後話

我這個人很堅持軟體開發標準,因為我相信如果大家都信奉一條標準,開發過程會變得更有效率,而且日後的維護和升級,都會簡單不少。我的團隊的開發標準制定地很詳細,所以我們看到 Bug , 可以在半個小時內,找到根源並修復。 復發幾乎沒有的事情。 而我們以前的程式碼(咳咳,不靠譜的前隊友)有些不按照規定來寫,修起來耗時間, 加功能更是幾乎不可能,修三四次,每次都有新問題, 原作者當時也離職了,他的程式碼也沒人看得懂。 最後,很多時候,只能重寫。 不過大體上一切都很easy, 我們在 Laravel 更新框架版本一個月後更新上去, 也沒有出過亂子。 我個人覺得,很大部分原因是因為我們保持了標準,而且我們的標準和Laravel官方的標準非常相似。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
Software Engineer Practices above all 軟體開發標準高於一切

相關文章