在使用 Laravel 函數時,咱們都避免不了使用其提供的各類各樣的全局函數,也稱爲輔助函數。php
主要集中爲處理數組、文件路徑、路由和字符串等。html
今天主要說說我喜歡的幾個經常使用 Helper 函數,以及 Helpers 實現原理,最後依葫蘆畫瓢,自定義咱們本身的全局函數。laravel
The data_get function retrieves a value from a nested array or object using "dot" notation:編程
The data_get function also accepts a default value, which will be returned if the specified key is not foundjson
data_get() 函數利用「.」符號,從嵌套數組或者對象中檢索數值,其中第三個參數是設置默認值,當檢索健不存在時。數組
$array = ['albums' => ['rock' => ['count' => 75]]];
$count = data_get($array, 'albums.rock.count');
// 75
$avgCost = data_get($array, 'albums.rock.avg_cost', 0);
// 0
$object->albums->rock->count = 75;
$count = data_get($object, 'albums.rock.count');
// 75
$avgCost = data_get($object, 'albums.rock.avg_cost', 0);
// 0
複製代碼
在多級嵌套中,並非每級 key 值都一致,對於同級不一樣 key 值,可使用通配符 (*) 代替,如:閉包
$array = ['albums' => ['rock' => ['count' => 75], 'punk' => ['count' => 12]]];
$counts = data_get($array, 'albums.*.count');
// [75, 12]
$array = ['albums' => ['rock', 'punk' => ['count' => 12]]];
$counts = data_get($array, 'albums.*.count');
// [NULL, 12]
複製代碼
對於我這英語很差的人來講,如何將單數形式寫成複數形式,有時候就會鬧出笑話了,但使用 str_plural() 方法,那就便捷多了,其中第二個參數是數值,若是大於 1 時,則轉爲複數形式,不然仍是單數形式。composer
str_plural('dog'); // dogs
str_plural('cat'); // cats
str_plural('dog', 2); // dogs
str_plural('cat', 1); // cat
str_plural('child'); // children
str_plural('person'); // people
str_plural('fish'); // fish
str_plural('deer', 2); // deer
str_singular('children') // child
複製代碼
同時也有複數轉單數函數:str_singular()框架
value() 函數根據傳入的值,返回數據,若是,傳入的是閉包函數,則會直接運行閉包函數,返回結果:函數
$result = value(5);
// 5
$result = value(function () {
return false;
});
// false
複製代碼
value() 我的以爲,更多用在於高階函數中,閉包函數做爲高階函數的傳值傳入;
和 value() 相比,能夠利用 with() 函數傳入參數值:
$callback = function ($value) {
return (is_numeric($value)) ? $value * 2 : 0;
};
$result = with(5, $callback);
// 10
$result = with(null, $callback);
// 0
$result = with(5, null);
// 5
複製代碼
<?php
function tap($value, $callback) {
$callback($value);
return $value;
}
複製代碼
傳入 value 值,並對 value 值進行操做,最後再返回 value。tap 函數就好將 value 值進行鍍金,修改 value 對象的狀態和屬性,最後返回結果能夠進行後續操做。如:
<?php
return tap($user)->update([
'name' => $name,
'age' => $age,
]);
複製代碼
當咱們傳入一個 $user model 到 tap 方法後,咱們就能夠鏈式各類 Model 函數,正常狀況下,update 方法返回的是 boolean 類型,正由於咱們用了 tap 函數,update 方法返回的是 user model 對象,能夠繼續鏈式 Model 方法,操做 user 模型對象。
更多全局 Helpers 函數,參見: laravel.com/docs/5.6/he…
當咱們在使用這些函數時,印入腦子裏的第一個問題就是:Laravel 是怎麼實現的?
因此咱們須要從 Laravel 框架源代碼入手。
在 PhpStorm IDE 轉到這些全局函數定義時,發現主要集中在這兩個文件中:
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
複製代碼
由於這些函數並非定義在對象中,而要達到全局加載的目標,Laravel 經過 Composer autoload 加載的方式載入:
引自:docs.phpcomposer.com/04-schema.h…
Files
若是你想要明確的指定,在每次請求時都要載入某些文件,那麼你可使用 'files' autoloading。一般做爲函數庫的載入方式(而非類庫)。
實例
{
"autoload": {
"files": ["src/MyLibrary/functions.php"]
}
}
複製代碼
接下來咱們看看其中一個函數是怎麼寫的:
if (! function_exists('tap')) {
/** * Call the given Closure with the given value then return the value. * * @param mixed $value * @param callable|null $callback * @return mixed */
function tap($value, $callback = null) {
if (is_null($callback)) {
return new HigherOrderTapProxy($value);
}
$callback($value);
return $value;
}
}
複製代碼
能夠看出,每一個函數都是以這種格式的:
if (! function_exists('xxx')) {
function xxx() {
// ...
}
}
複製代碼
注: 從 tap 函數源代碼能夠看出,不管傳入的閉包函數有沒有返回值,函數返回的值,都是 $value,和傳入的值同樣,這樣也就達到「鏈式編程」的目標。
若是以上 Helpers 函數還知足不了你的話,咱們就能夠經過上文的方式來自定義 Helpers 函數,來知足咱們本身的開發需求。
主要有如下幾步:
- 在項目中建立 helper.php 文件
- 在 composer.json 中將 helper 文件 autoload 載入
- composer dump-autoload
- 在 helper.php 文件寫入咱們的全局函數
- test
舉個栗子 🔽
學習 Laravel Helpers 實現原理,不只有助於咱們理解和使用這些 Helpers 方法,而且,經過研究每個 Helper 函數是怎麼寫的,也有助於規範咱們代碼邏輯和思惟。學其之所長。
參考: