Laravel で、ユーティリティクラスを作る必要が生じたときに、配置などに悩んだことはないでしょうか? 実装が簡単で Laravel の枠組みにしっかりと準じる方法として考えたいのがヘルパー関数です。
Laravel がいうところのヘルパー関数とは、グローバルな共通関数のことになります。
メリットは、どこからでも呼ぶことができ、いちいちuse
で使用を宣言する必要もありません。
すでに使用されている共通関数
Laravel でプログラミングをしていると、ヘルパ-関数を意識せずに使用していると思われます。
コントローラの各メソッドの最後で、view
を使用していないでしょうか?
view
はヘルパー関数になります。
vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
if (! function_exists('view')) {
/**
* Get the evaluated view contents for the given view.
*
* @param string|null $view
* @param \Illuminate\Contracts\Support\Arrayable|array $data
* @param array $mergeData
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
function view($view = null, $data = [], $mergeData = [])
{
$factory = app(ViewFactory::class);
if (func_num_args() === 0) {
return $factory;
}
return $factory->make($view, $data, $mergeData);
}
}
このファイルには、view
以外にもヘルパー関数が定義されています。
vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
以外にも、
vendor/laravel/framework/src/Illuminate/Support/helpers.php
にもハルパーの関数は定義されています。
以下の公式ドキュメントにはすべてのヘルパー関数が記載されています。 https://laravel.com/docs/8.x/helpers#method-array-accessible
autoloadのしくみ
ヘルパー関数を利用する際に、use
が不要なのはcomposer
のautoload
機能で作られたファイルを Laravle がindex.html
でrequire
しているからです。
/var/www/html/todo/public/index.php
require __DIR__.'/../vendor/autoload.php';
このしくみにより、Laravel ではrequire
を記述することがありません。
vendor/autoload.php
については下記になります。
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit23ab39906b1c8511784f28bd001d9b73::getLoader();
autoload_real.php
にて定義されたComposerAutoloaderInit23ab39906b1c8511784f28bd001d9b73
クラスのgetLoader
メソッドで、
composer.json
の autoload で指定されたものを load するしくみになっています。
vendor/laravel/framework/composer.json
は下記になります。
"autoload": {
"files": [
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
],
"psr-4": {
"Illuminate\\": "src/Illuminate/"
}
},
files
にて前述の 2 つのファイルが指定されています。
関数だけでなく定数の定義にも利用できます。
定数の定義は、config/const.php
ファイル、クラスのstaticプロパティ
の方法が知られていますがautoload
でも実現できます。
独自のヘルパー関数の定義方法
helpers.phpファイルの作成
app
直下にhelpers.php
を作成し関数を定義します。
定義する関数は、チュートリアルのLaravel入門(第12回)で解説したマルチバイト文字のtrimとします。
<?php
if (! function_exists('multibyte_trim')) {
/**
* マルチバイト対応trim
*
* @param string $value
* @return string
*/
function multibyte_trim($value)
{
return preg_replace('/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $value);
}
}
Composer.jsonファイルへの追加
helpers.php
を autoload の対象に追加します。
files
というキーを作りファイルを指定します。
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
"files": [
"app/helpers.php"
]
},
Composer dump-autoloadコマンド実行
composer.json
ファイルへの追加作業が完了したら、comoser dump-autoload
コマンドを実行します。
$ composer dump-autoload
このコマンドにて autoload のためのファイル群を最新状態にします。 参考:https://getcomposer.org/doc/01-basic-usage.md#autoloading
動作確認
tinker
にて動作を確認します。
$ php artisan tinker
全角空白をUnicodeポイント
で指定し文字「1」の前後に付加しています。
>>> \IntlChar::chr("\u{3000}")."1".\IntlChar::chr("\u{3000}");
=> " 1 "
前後に全角空白が付加されています。
ヘルパー関数として定義したmultibyte_trim
を使用します。
>>> multibyte_trim(\IntlChar::chr("\u{3000}")."1".\IntlChar::chr("\u{3000}"));
=> "1"
前後の全角空白が取れて「1」のみが表示されています。
まとめ
Java などのオブジェクト指向的な言語では、ユーティリティクラスを作って対応するものが PHP では関数にて対応できます。
ユーティリティクラスは、実装が少し面倒であり、そして使用する際にuse
が必要になってきます。
Laravel ではグローバル関数として定義できてお手軽です。
しかし、なんでもかんでもグローバル関数であるヘルパー関数に定義するのもよくありません。 Laravel でも一連の操作の塊としてユーティリティクラス的なものがあります。
それらは、配列、文字列などの操作を簡単にするユーティリティクラスです。 各メソッドは static で定義されています。
Illuminate\Support\Arr
Illuminate\Support\Collection
Illuminate\Support\Str
バージョン 5.7 以降では、このようなユーティリティクラスも Helpers として公式ドキュメントに紹介されています。
これらは、たしかにヘルパーですが、もはやグローバル共通関数であるヘルパー関数ではなく使用に際してはuse
が必要です。