====== Apricot 特徴と概要 ====== --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-07-29// [[apricot:usage:ja|Apricot ドキュメント に戻る]] 目次 * Apricot 特徴と概要 * [[apricot:usage:ja:config|Apricot 配置と構成]] * [[apricot:usage:ja:errors-logging|Apricot ログとエラー処理]] * [[apricot:usage:ja:http|Apricot リクエストとレスポンス]] * [[apricot:usage:ja:frontend|Apricot フロントエンド]] * [[apricot:usage:ja:database|Apricot データベース]] * [[apricot:usage:ja:model|Apricot モデルとサービス]] * [[apricot:usage:ja:middleware|Apricot ミドルウェア]] * [[apricot:usage:ja:controller|Apricot コントローラ]] * [[apricot:usage:ja:validation|Apricot バリデーション]] * [[apricot:usage:ja:provider|Apricot サービスプロバイダー]] * [[apricot:usage:ja:authentication|Apricot ユーザ認証]] * [[apricot:usage:ja:utility|Apricot ユーティリティ]] ---- ===== 特徴 ===== Apricot は PHPによるWebアプリケーションのフレームワークで、比較的小規模なアプリケーションの構築を素早く行えることを目的としています。Apricot は [[https://github.com/laravel/framework|Laravel]] に大きな影響を受けていますが、Laravelようなフルスタックなフレームワークではなく、軽量なコアを持ったフレームワークです。 Apricotでは、フレームワークの主要な部分だけを独自に実装し、他のコンポーネントは、秀作な外部ライブラリーを取り込んで開発されています。テンプレートエンジンにはLaravelと同じBladeを使用している他、環境設定のPhpdotenv、ログ出力のMonolog、そしてエラーハンドラーのwhoopsもLaravelと同じコンポーネントを使用しています。その他でもLaravelと同じ識別子やコーディングスタイルを使用しているので、Laravelユーザには見慣れたコードになっています。 一般的なWebアプリケーションのフレームワークでは、リクエストルータ、リクエストクラス、レスポンスクラス、ORM、テンプレートエンジン、ミドルウェアやコントローラの基底クラス、DIコンテナ―、ロガー、エラーハンドラー、そしてそれ以外の様々な機能を持ったライブラリーや部品などから構成されており、Laravelのようなフルスタック・フレームワークでは、これらが1つのフレームワークとしてパッケージ化されています。 これらのフルスタック・フレームワークの利用は、中規模以上のアプリケーション開発では、開発効率や保守性に関して大きな効果が期待できますが、比較的小規模なアプリケーション開発では、フレームワークに関連する学習、調査、ファイルの編集、またはフレームワークのルールに従ったカスタマイズに多くの時間を費やされる場合も少なくありません。Apricot はこのような問題を解決するために、フレームワークのコアを出来るだけ軽量にし、カスタマイズ可能な部分をできるだけフレームワークの外側(即ち、アプリケーション部分)に配置するようにしました。 この問題解決により、比較的小規模なアプリケーション開発に於いて、アプリケーション全体のコードの肥大化を抑止し、また外部ライブラリーの相互運用性を高める効果も期待できます。フレームワークの選択は、開発すべきアプリケーションの規模と特性に依存すべきで、Apricotの存在がフレームワークの選択肢を広げることを期待しています。 \\ ==== Apricot のコア(Core)部分 ==== Apricot はコア(Core)とアプリ(App)の2つの部分から構成されていますが、上記の理由により、Apricot のコアは Webアプリケーションの中心的な部分であるリクエストからレスポンスまでの以下に示す機能を中心に構成されています。 * HTTPリクエストの取得 * HTTPレスポンスの生成 * リクエストに応じたアクションの発動 * ミドルウェアの発動 そして、これらの主要機能に加え、次の機能をApricot 独自で実装しています。 * 構成管理(コンフィグレーション) * 多言語対応(トランスレーション) これら以外のコア機能は、以下の外部ライブラリーを使用しています。 * 環境変数 --- [[https://github.com/vlucas/phpdotenv|phpdotenv]] * ログ出力 --- [[https://github.com/Seldaek/monolog|monolog]] * リクエストルーター --- [[https://github.com/nikic/FastRoute|FastRoute]] * DIコンテナ --- [[https://github.com/thephpleague/container|League/Container]] * テンプレートエンジン --- [[https://github.com/EFTEC/BladeOne|bladeone]] * エラーハンドラー --- [[https://github.com/filp/whoops|Whoops]] また、運用時のデバッグツールとして以下のライブラリーを組み込んでいます。 * デバッグ出力 --- [[https://github.com/maximebf/php-debugbar|php-debugbar]] \\ ==== Apricot のアプリ(App)部分 ==== アプリ部分はコアの機能を使って実装されます。アプリ部分の実装は、コントローラとミドルウェアの具象化が主な作業になります。これらの基底クラスは、コア部分に存在します。コントローラは、クライアントからの特定のリクエストを処理してレスポンスを生成するクラスです。ミドルウェアは一般に全てのまたは限定的なリクエストを幅広く処理するクラスで、コントローラによって形成されるアプリケーション層からは分離された存在です。両者は共にリクエストを処理して、最終的に何れかのクラスがレスポンスを生成します。 Apricotでは、これらのコンポーネントがリクエストを処理する過程で使用するデータモデルに関連するコンポーネントをアプリ部分に配置します。データモデルの基底クラスはApricot独自で実装されていますが、他のコンポーネントには、以下の外部ライブラリーを使用しています。 * ORマッパー --- [[https://github.com/j4mie/idiorm|idiorm]] * バリデーター --- [[https://github.com/vlucas/valitron|Valitron]] これらのデータモデル関連のコンポーネントは、単なるサンプルに過ぎず、Apricotユーザは好みに応じていつでも変更することができます。また、必要に応じて他の外部ライブラリーから必要なコンポーネントを追加して最適なアプリケーションを構成するようにして下さい。汎用的な独自のアプリケーション構成が完成したら、それを新しいフレームワークとしてライブラリー化し、同種のアプリケーションに適用することもできます。 \\ ===== 名前空間 ===== Apricotのアプリ部分の名前空間は、''\App'' です。アプリのソースコードはプロジェクトディレクトリー下の ''app'' に配置されます。一方、コア部分の名前空間は、''\Apricot'' です。これは、Apricotをプロジェクトとしてインストールした場合は、プロジェクトディレクトリー下の ''core'' に配置され、ライブラリーとしてインストールした場合は、Composerのルールに従い、''vendor/y2sunlight/apricot/core'' の下に配置されます。 \\ ===== ボイラープレートとシングルトン ===== Apricotでは、コントローラ、ミドルウェアそしてテンプレートの中でフレームワークを呼び出す簡便な方法として、ボイラープレートとシングルトンを提供しています。 ボイラープレートとは良く使うフレームワークのコードパターンを関数として使用できるようにしたヘルパー関数です。例えば: $app_name = env('APP_NAME'); $log_name = config('monolog.name'); ''env()'' は環境変数の取得を、''config()'' はドット表記で指定された構成変数の値を取得するボイラープレートです。ボイラープレートについては、このドキュメントの[[apricot:usage:ja:utility#ボイラープレート|ユーティリティー]]の章を参照して下さい。 以下は、ログ出力を行うシングルトンの例です。 Log::error($message); Logクラスは、[[https://github.com/Seldaek/monolog|monolog]]のLoggerクラスをラップしたシングルトンで、''Log::error()'' はエラーレベルのログを出力するメソッドです。このコーディングは Laravelではお馴染みのファザードと同じスタイルをしています。Apricotのシングルトンは全てこのような静的アクセススタイルでメソッドを利用できるようになっています。 この他にもリクエストを取得する、Input、Session、Cookie、またはテンプレートエンジンのViewなどApricotでは様々なシングルトンが存在します。こららのシングルトンは、アプリケーションのどこからでも使用することができます。 このように、Apricotでは、ボイラープレートとシングルトンを使用した素朴で簡単なスタイルでコーディングができるようになっています。 \\ ===== Apricotの概要 ===== Apricotの概要を知る為に、クライアントのリクエストを受け取ってからApricotがレスポンスを返すまでを、ユーザ登録アプリケーションを例に説明します。 \\ ==== リクエストルータ ==== リクエストルータは、アプリケーションのエンドポイントがどの ''コントローラ@アクション'' を実行するのかを決定します。Apricotでは、リクエストルータに [[https://github.com/nikic/FastRoute|FastRoute]]を使用しています。ルーティングの設定は、''config/routes.php'' ファイルを編集することで行います。 以下は、ユーザ登録ページの CRUD操作(create, read, update, and delete)に対するルーティングの例です。 getRouteBase(); // Creates a route group with a common prefix. $r->addGroup($base, function (FastRoute\RouteCollector $r) use($base) { // User $r->get ('/users', 'UserController@index'); $r->get ('/user/create', 'UserController@create'); $r->post('/user/insert', 'UserController@insert'); $r->get ('/user/{id:\d+}/edit', 'UserController@edit'); $r->post('/user/{id:\d+}/update', 'UserController@update'); $r->post('/user/{id:\d+}/delete', 'UserController@delete'); }); }; \\ ==== ミドルウェア ==== ミドルウェアは、ルーティングによって決定されたコントローラの前後でリクエストを処理し、必要に応じてレスポンスを生成することができます。ミドルウェアがレスポンスを生成した場合、コントローラのリクエスト処理は行われません。以下は、セッションを利用してユーザ認証を行うミドルウェア(セッション認証)の例です。 exclude)) { return $next->invoke(); } // Verifys whether user is authenticated. if (AuthUser::verify()) { return $next->invoke(); } // Redirect to login page If not authenticated. return redirect(route('login')); } } アプリ部分に実装されるミドルウェアの全ての具象クラスは、process() メソッドを実装する必要があります。 ミドルウェアは全てのコントローラに介入しますが、$exclude変数に登録されているコントローラは除外します。''AuthUser'' は認証ユーザクラスのシングルトンで、''AuthUser::verify()'' はユーザ認証をチェックするメソッドです。ユーザ認証に成功すると次のインポーカー( $next ) にミドルウェアまたはコントローラ@アクションをインボークさせ、失敗した場合は、ログインページ( route('login') )にリダイレクトします。 Apricotでは、以下のミドルウェアがアプリとして app/Middleware 内に初期実装されています。 * ユーザ認証(基本認証 及び セッション認証) * アクセスログ * CSRF対策 これらは必要に応じて直接カスタマイズできます。また、アプリケーションの設定ファイル config/app.php を編集することにより新しいミドルウェアを追加することができます。 [ \App\Middleware\AccessLog::class, /* Access log */ \App\Middleware\VerifyCsrfToken::class, /* Verify CSRF Token */ \App\Middleware\Auth\SessionAuth::class, /* Session authentication */ \App\Middleware\InputConverter::class, /* Input Converter */ \App\Middleware\MyMiddleware::class, /* New MyMiddleware */ ], ]; \\ ==== コントローラ ==== ルーティングによって設定されているエンドポイントがアクセスされ、ミドルウェアによってレスポンスが生成されなかった場合、Apricotはコントローラ@アクションをインボークします。コントローラの全ての具象クラスはApricotのアプリ部分の ''App\Foundation\Controller'' を継承し、このControllersクラスは、コア部分の ''Apricot\Foundation\BaseController'' を継承しています。コントローラはプロジェクトディレクトリー下の ''app/Controllers'' に配置する必要があります( 名前空間は''\App\Controllers'' です )。 コントローラの継承関係 ConcreteController => Controller => BaseController BaseController クラスの主な機能はコントローラーに[[#インターセプター]]を登録する事です。また、Controller クラスにはアクションに[[#トランザクション]]をサポートさせる機能があります。 以下はユーザコントローラの例です。ここには、コンストラクタと空のアクションメソッドを示します。 user = $user; // Registers interceptors. $this->intercept('insert', 'UserInterceptor@insert'); $this->intercept('update', 'UserInterceptor@update'); // Registers transactional actions. $this->transactional('insert','update','delete'); } public function index(){} /* Users list page. */ public function create(){} /* User registration page. */ public function insert(){} /* Inserts a user record. */ public function edit(int $id){} /* User edit page. */ public function update(int $id){} /* Updates a user record. */ public function delete(int $id){} /* Deletes a user record. */ } コントローラのコンストラクタは、Auto Wiring 機能をサポートします。これは、コンストラクター引数の型ヒントを調べることにより、オブジェクトとそのすべての依存関係を再帰的に自動的に解決する機能です。但し、注入できるのはオブジェクト型の変数だけです。Auto Wiring には外部ライブラリーの [[https://github.com/thephpleague/container|League/Container]] を使用しています。 Auto Wiring 機能で使用する引数には、一般的にモデルクラスやサービスクラスを指定します。ここでは、ユーザモデルをコンストラクター引数に指定し、それをメンバ変数に格納しています。 また、上のコンストラクタではコントローラのアクションに[[#インターセプター]]を登録したり、アクションを[[#トランザクション|トランザクション化]]していますが、それらについては、以下の項を参照して下さい。 \\ ==== HTTP リクエストの取得 ==== 通常のフレームワークでは、CGIやPHP環境からアプリケーションに到達したすべてのデータ($_SERVER、$_GET、$_POST、$_FILES、$_SESSIONなどの変数)を1つのリクエストクラスにカプセル化します。リクエストクラスでは、これらのデータに加え、フラッシュと呼ばれる、一度だけ保存されるセッション変数(次の画面の遷移のときまで保存される変数)もサポートされています。 Apricotにはリクエストクラスがありません。その代わりに、個々の変数をカプセル化したクラスのシングルトンを持っています。リクエスト取得用に以下のシングルトンがあります: * Input --- フォーム送信データ(GET変数またはPOST変数:methodに依存) * QueryString --- クエリ文字列(GET変数) * Session --- SESSION変数 * Flash --- 1回限り有効なSESSION変数 * Cookie --- COOKIE変数 これらはシングルトンなので、アプリケーションのどこからでもリクエストを取得することができます。以下は、ユーザコントローラのinsertアクションでリクエストを取得している例です。 /** * Inserts a user record. * * @return \Apricot\Foundation\Response */ public function insert() { $inputs = Input::all(); // Do something. // ... } ''Input'' はフォームから送信データ(入力変数)を保持するクラスのシングルトンで、''Input::all()'' は全ての入力変数を取得するメソッドです(このコーディングは Laravelではお馴染みのファザードと同じスタイルをしています)。Apricotのシングルトンは全てこのような静的アクセススタイルでメソッドを利用できるようになっています。 \\ ==== HTTP レスポンスの生成 ==== 以下は、ユーザコントローラの編集フォームを表示するアクションの例です。 /** * User edit page. * * @return \Apricot\Foundation\Response */ public function edit(int $id) { // Finds By the primary key $user = $this->user->findOne($id); if ($user!==false) { return render("user.edit", ["user"=>$user]); } else { return redirect(route("users"))->withOldErrors(); } } URIに含まれるユーザID( $id )からユーザモデル( $this->user )を使って、ユーザ情報を取得しています。findOne() は、主キーによる検索を行うモデルのメソッドです。 ユーザ情報の取得が成功した場合、ボイラープレート render() を呼び出して、HTMLをレンダリングします。render() の第1引数にはHTMLテンプレート名、第2引数にはテンプレート変数を[変数名 => 値]の形で渡します。ユーザ情報の取得が失敗した場合、エラー情報を添付して( withOldErrors() )、''users'' にリダイレクトしています。 アクションの戻り値はレスポンスオブジェクトです。レスポンスには、この例のように、レンダーレスポンスとリダイレクトレスポンスの2つがあり、Aprocotはアクションの戻り値がどちらのタイプのレスポンスかによって適切なレスポンスを生成します。 \\ ==== インターセプター ==== ユーザコントローラのコンストラクタには次のようなコードがあります。 // Registers interceptors. $this->intercept('insert', 'UserInterceptor@insert'); $this->intercept('update', 'UserInterceptor@update'); ''$this->intercept()'' はベースコントローラクラスのメソッドで、アクションにインターセプターを登録します。例えば、上の insert アクションの例では、このアクションに UserInterceptorクラスのinsertメソッドをインターセプターとして登録しています。インターセプターはプロジェクトディレクトリー下の app/Controllers/Interceptors に配置する必要があります( 名前空間は\app\Controllers\Interceptors です )。 インターセプターの目的はアクションに信頼性のある入力データを渡すことで、主な用途には以下のようなものがあります。 * 入力データの検証(バリデーション) * 不要な入力データのフィルタリング * 入力データの変換 インターセプターはエラーがない場合は、voidを返しますが、バリデーションエラーなどがあった場合はレスポンスオブジェクトを返して以降のアクションを中止することができます。 以下にインターセプター( UserInterceptor@insert )の例を示します。インターセプターの第1引数はコントローラーのインスタンスで、その後にアクションと同じの引数が続きます。このメソッドの場合はコントローラの intser アクションに引数が無いので、intser インターセプター引数は1つだけです。 この例では、バリデーション後に、''Input::remove()'' を使用して、バリデーションだけで使用する入力変数を削除しています。完全なインターセプターの例は、次の項を参照して下さい。 \\ ==== バリデーション ==== Apricotでは サーバ側のバリデーションに[[https://github.com/vlucas/valitron|Valitron]] を使用しています。以下に、前項で示したインターセプター( UserInterceptor@insert )の完全な例を示します。 /** * Interceptor for insert method. * * @return void|\Apricot\Foundation\Response return Response if failed */ public function insert(Controller $controller) { $inputs = Input::all(); // Validation $v =(new \Valitron\Validator($inputs)) ->rule('required', ['account','password']) ->labels(inputLabels('messages.user.create')); if(!$v->validate()) { $errorBag = new ValidatorErrorBag($v->errors()); return redirect(back())->withInputs()->withErrors($errorBag); } // Removes unnecessary inputs Input::remove('password_confirmation'); } この例では、''Input::all()'' で入力変数を取得した後に、''Validator''のインスタンスを生成しています。 Validatorの ''rule()'' メソッドは入力変数に検証ルールを適用します。この例では、必須入力を意味する''required'' ルールを入力変数の account と password に適用しています。また、''labels()'' メソッドはエラーメッセージで使う項目名を設定しています。 バリデーションの実行は ''validate()'' メソッドで行います。バリデーションが失敗した時、''withInputs()'' で入力変数を、withErrors() でバリデーションのエラーバッグをフラッシュ変数に保存します。そして、redirect()で前画面にリダイレクトするレスポンスオブジェクトを生成し、それを返します。Apricotは、インターセプターがレスポンスオブジェクトを返した時、コントローラーアクションを呼び出さずに、そのレスポンスをクライアントに返します。 バリデーションの詳細は [[https://github.com/vlucas/valitron/blob/master/README.md|Valitron の README]] をご覧下さい。 \\ ==== トランザクション ==== ユーザコントローラのコンストラクタには次のようなコードがあります。 // Registers transactional actions. $this->transactional('insert','update','delete'); ''$this->transactional()'' はアクションをトランザクション化するコントローラクラスのメソッドです。上の例では insert、update そして deleteアクションをトランザクション化しています。 Apricotは、アクションを呼び出す前にトランザクションを開始し、アクションが例外をスローしなかった場合、トランザクションが成功したものとみなして、そのトランザクションをコミットします。一方、アクションが ''ApplicationException'' 例外をスローした場合、Apricotは、それをキャッチしてエラーログを出力して、アクションに代わって前画面に戻るリダイレクトレスポンスを生成します。 \\ ==== モデル ==== Apricotの個々のモデルクラスは、''\App\Foundation\Model'' から継承して作りますが、このクラスはカスタマイズされることを前提としています。初期に実装されている ''Model'' クラスは ORMに [[https://github.com/j4mie/idiorm|Idiorm]] を使用し、以下のメソッドを実装しています。 * findAll() --- 全件検索 * findOne(int $id) --- 主キー検索 * create(array $inputs=null) --- モデルの新規作成 * insert(array $inputs) --- レコードの挿入 * update($id, array $inputs) --- レコードの更新(楽観的ロック付き) * delete($id) --- レコードの削除 これらの実装では、アプリケーションで使用する全てのテーブルが以下のカラムを持っていることが仮定されています。 * created_at (text) --- 作成日 * updated_at (text) --- 更新日 * version_no (integer) --- バージョンNo(楽観的ロックで使用) このように、初期実装されている ''Model'' クラスには幾つかの前提があるので、アプリケーションに合わせてカスタマイズまたは再作成した方が良いかもしれません。また、ORMも [[https://github.com/j4mie/idiorm|Idiorm]] 以外のものを使うことができます。 以下は、初期実装されている ''Model'' クラスを継承したユーザモデルの例です。個々のモデルクラスは、''\App\Models'' の下に配置されます。 ユーザモデルでは、insert() と update() メソッドをオーバーラードしています。insert() では入力された ''password'' を暗号化してデータベースに保存しています。update() では入力された''password'' が入力されていない場合は、入力変数から除外し、そうでない場合は、暗号化してデータベースに保存しています。 \\ ==== HTMLテンプレート ==== Apricotでは、テンプレートエンジンにLaravelと同じBladeを使用しています。実際に使用しているライブラリは [[https://github.com/EFTEC/BladeOne|BladeOne]] です。BladeOneは、Blade のスタンドアロンバージョンです。 以下は、ユーザコントロールの index アクションの例です。 public function index() { $users = $this->user->findAll(); return render("user.index", ["users"=>$users]); } ここでは、ボイラープレート''render()'' を使って、HTMLをレンダリングし、それをレスポンスとして返しています。render() の第1引数にはHTMLテンプレート名、第2引数にはテンプレート変数を[変数名 ⇒ 値]の形で渡します。 以下に、テンプレートの例( user.index )を示します。 {{-- Parent layout --}} @extends('layout') {{-- title --}} @section('title', __('messages.user.index.title')) {{--content --}} @section('content')
@foreach($users as $user) id}/edit")}}"> @endforeach
{{__('messages.user.index.id')}} {{__('messages.user.index.account')}} {{__('messages.user.index.email')}} {{__('messages.user.index.created_at')}}
{{ $user->id }} {{ $user->account }} {{ $user->email }} {{ ViewHelper::formatDatetime($user->created_at) }}
@endsection
テンプレートファイルは、プロジェクトディレクトリ下の ''assets/views/'' に配置します。一般的にテンプレートファイルは、''assets/views/{path}/{name}.blade.php'' として保存します。''{path}'' はサブディレクトリ下に配置したい場合のオプションですが、コントローラ名に関連した名前付けが一般的でしょう。上例のテンプレートファイルは、''assets/views/user/index.blade.php'' に配置しているので、テンプレート名は ''user.index'' になります。 上の例で見られる、@extends、@section 及び @endsection、@foreach 及び @endforeach は Blade のディレクティブです。また、''{{ $name }}'' は $name を表示するための Blade の構文です。詳しくは以下のドキュメントを参照して下さい。 * https://github.com/EFTEC/BladeOne --- BladeOne * https://readouble.com/laravel/5.8/ja/blade.html --- laravel5.8のblade ''__( $key )'' はトランスレータを呼び出すApricotのボイラープレートです。詳しくは次項の[[#多言語化]]を参照して下さい。また、''ViewHelper'' はテンプレートヘルパーを実装するためのクラスで、''app/Helpers/'' の下に配置されています。''ViewHelper::formatDatetime()'' は日付を指定の書式で返すヘルパー関数です。 === クラスアリアス === テンプレートヘルパーやシングルトン( Input, Session, Flashクラス など )はクラスアリアスが登録されているので、PHPのuse演算子や完全修飾した名前空間を使用することなく、テンプレートの中で使用できます。クラスアリアスの登録は ''config/setup/aliases.setup.php'' の中で以下のようにされています。 Apricot\Input::class, 'QueryString' => Apricot\QueryString::class, 'Session' => Apricot\Session::class, 'Flash' => Apricot\Flash::class, 'Cookie' => Apricot\Cookie::class, 'Config' => Apricot\Config::class, 'Log' => Apricot\Log::class, 'Debug' => Apricot\Debug::class, 'DebugBar' => Apricot\DebugBar::class, 'ErrorBag' => Apricot\Foundation\ErrorBag::class, /* App */ 'ViewHelper' => App\Helpers\ViewHelper::class, 'ValidatorErrorBag' => App\Foundation\ValidatorErrorBag::class, 'AuthUser' => App\Foundation\Security\AuthUser::class, ]; // Creates an alias for a class foreach($aliases as $alias_name => $original_class) { class_alias($original_class, $alias_name); } return true; // Must return true on success }; \\ ==== 多言語化 ==== Apricotは多言語をサポートしています。''Lang'' シングルトンの ''Lang::get()'' メソッドはドット表記で指定されたキーから各言語用のメッセージを取得します。Apricotがどの言語を選択するかは、ブラウザで使用されている言語と準備されている言語ファイルによって自動的に決定されます。デフォルトの言語は、環境変数 ''APP_LANG'' で指定してます。この変数が指定されていない場合は英語になります。 $message = Lang::get('messages.user.index.account'); ''Lang::get()'' メソッドはボイラープレートを使って次のようにも記述できます。 $message = __('messages.user.index.account'); 各言語用のメッセージはプロジェクトディレクトリー下の ''assets/lang/{言語コード}/'' に配置された言語ファイルの中に保存され、そのファイル名がドット表記の最初のキーとなります。即ち、''messages'' で始まるキーを持つメッセージは 各言語毎に以下のファイルに保存されます。 your-project [プロジェクトディレクトリー] | ├── assets | | | ├── lang | | | | | ├── ja | | | ├── messages.php | | | | | ├── en | | | ├── messages.php 以下に、messages.php の例を示します。 [ 'index'=> [ 'title'=>'ユーザ一覧', 'id'=>'ID', 'account'=>'アカウント', 'email'=>'メールアドレス', 'note'=>'備考', 'created_at'=>'登録日', 'btn_new'=>'新規', ], ], ]; \\