Laravel5.5: 公式ドキュメントでは言及されていないヘルパー関数

  • 6
    Like
  • 0
    Comment

下記のように、公式ドキュメントにはヘルパー関数が列挙されているページがあります。
しかし、調べてみるとこの他にもグローバルに使えるヘルパー関数がありました。
:link: (日本語) ヘルパ
:link: (英語) Helpers

(2017年10月15日 追記)
Laravel5.5では「Miscellaneous(その他)」の欄が設けられたので、ほぼ全てのヘルパー関数が上記のページ内で説明されています。
ただ、それでもまだ4つの関数の説明がありませんでした。

ヘルパー関数を定義しているファイル

2つのファイルに分けて定義しているようです。

ヘルパー関数である証拠

上のファイルは下記のようにcomposer.jsonautoloadに指定されて読み込まれています。
helpers.phpはクラスファイルではなく単に関数を列挙しただけのファイルなので、filesキーで指定されてます。
:link: つべこべ言わずComposerでシンプルにautoloaderを使用したいとき - Qiita
:link: (公式解説) autoload
:link: (公式解説) files

:page_facing_up: framework/composer.json

{
    "autoload": {
        "files": [
            "src/Illuminate/Foundation/helpers.php",
            "src/Illuminate/Support/helpers.php"
        ],
        "psr-4": {
            "Illuminate\\": "src/Illuminate/"
        }
    },

ヘルパー関数の解説ページにはない関数一覧

さて、本題です。
cookieのように、ヘルパー関数のページではなくとも公式ドキュメント内の別のページで説明されているものもあります。
しかし、windows_osのように全く言及のない関数も多いです。
車輪の再発明をしないよう、ヘルパー関数を自作する前に確認しておきたいです。

たちの悪いことに、ヘルパー関数はグローバルゆえにどのクラスにも属していないので、APIリファレンスにも載っていません。
下記の関数は、ソースコードを読んで見つけるしかありません。
ただ、無秩序に定義されているわけではなくcomposer.jsonに明記されているので、それほど面倒ではないと思います。

Foundation/helpers.php

関数 コメント文
elixir Get the path to a versioned Elixir file.

Support/helpers.php

関数 コメント文
append_config Assign high numeric IDs to a config item to force appending.
object_get Get an item from an object using "dot" notation.
windows_os Determine whether the current environment is Windows based.

(余談) 上に挙げた関数の見つけ方

定義済みの全ての関数を取得するget_defined_functionsと、配列同士の差分を取得するarray_diffを使いました。

// 下記のページの「Available Methods」に列挙されている関数名をコピーして、配列として整形する。
// https://laravel.com/docs/5.5/helpers
$arrDocs = [
    'array_add',
    'array_collapse',
    'array_divide',
    // ...
];

// 下記の2つのファイルの中身を丸ごとコピーして貼り付ける
// vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
// vendor/laravel/framework/src/Illuminate/Support/helpers.php
if (! function_exists('abort')) {
    function abort($code, $message = '', array $headers = [])
    {
        app()->abort($code, $message, $headers);
    }
}
// ...

// 定義済みの全ての関数を取得する
$arr = get_defined_functions();

// 配列同士の差分を取得する
$diff = array_diff($arr['user'], $arrDocs);
foreach ($diff as $val) {
    echo $val.'<br>';
}

(余談) Laravel由来ではないグローバル関数も存在する

symfony/polyfill-mbstringhamcrest/hamcrest-phpなど、Laravel以外のパッケージで定義されたグローバル関数もLaravel内で使えるようです。
下記のようにLaravel内で即席のルートを作り、先ほどと同じくget_defined_functionsarray_diffを使って調査しました。

routes/web.php
// 即席のルートを定義
Route::get('get-global-functions', function() {
    $arrHelpers = [
        // 先ほどの調査で得た、全てのLaravelのヘルパー関数を配列として格納する
        'array_add',
        'array_collapse',
        'array_divide',
        // ...
    ];
    $arr = get_defined_functions();
    $diff = array_diff($arr['user'], $arrHelpers);
    $return = '';
    foreach ($diff as $val) {
        $return .= $val.'<br>';
    }
    return $return;
});

結果、下記のようにたくさんのグローバル関数が定義されていることが分かりました。
これらはLaravelが公式に提供しているものではないので、流用しないほうがいいでしょう。
Laravelがそのパッケージに依存しなくなったら使えなくなってしまいますから。
それにしても、ヘルパー関数を定義する前にいちいちif (! function_exists('関数名'))で重複を検査する理由は、このように他のパッケージのグローバル関数名と衝突する危険があるからなのだということが分かり、勉強になりました。

composerrequiredd08af2877ca94bd2ded2cefe5883ad7, composer\autoload\includefile, assertthat, anarray, hasiteminarray, hasvalue, arraycontaininginanyorder, containsinanyorder, arraycontaining, contains, haskeyinarray, haskey, haskeyvaluepair, hasentry, arraywithsize, emptyarray, nonemptyarray, emptytraversable, nonemptytraversable, traversablewithsize, allof, anyof, noneof, both, either, describedas, everyitem, hastostring, is, anything, hasitem, hasitems, equalto, identicalto, aninstanceof, any, not, nullvalue, notnullvalue, sameinstance, typeof, set, notset, closeto, comparesequalto, greaterthan, greaterthanorequalto, atleast, lessthan, lessthanorequalto, atmost, isemptystring, emptystring, isemptyornullstring, nulloremptystring, isnonemptystring, nonemptystring, equaltoignoringcase, equaltoignoringwhitespace, matchespattern, containsstring, containsstringignoringcase, stringcontainsinorder, endswith, startswith, arrayvalue, booleanvalue, boolvalue, callablevalue, doublevalue, floatvalue, integervalue, intvalue, numericvalue, objectvalue, anobject, resourcevalue, scalarvalue, stringvalue, hasxpath, mb_ord, mb_chr, mb_scrub, psy\sh, psy\debug, psy\info, psy\bin, debugbar, debug, start_measure, stop_measure, add_measure, measure

なお、get_defined_functionsで取得した関数名は強制的に小文字になります
上に挙げた関数名は、本来は大文字の場合もあるので気をつけてください。
ただ、PHPの名前空間名、クラス名、メソッド名、関数名はケース・センシティブではない、つまり大文字小文字を区別しないので、問題ないでしょう。
(※変数名、定数名、プロパティ名はケース・センシティブです)
このような事情から、ヘルパー関数の名前はスネークケースにした方がいいと思います。
詳しくは下記をご覧ください。
:link: PHPのグローバルなユーザー定義関数の名前はスネークケースにするべきだと思う