Laravel 5.dev フレームワークの拡張

マネージャーとファクトリー

ドライバーベースのコンポーネントの作成を管理する、複数のManagerクラスをLaravelは持っています。それらは、キャッシュ、セッション、認証、キューコンポーネントです。Managerクラスはアプリケーションの設定に基づき、特定のドライバーの実装を作成することに責任を持っています。例えば、CacheManagerクラスはAPC、Memcached、ファイル、その他のキャッシュの実装を生成することができます。

各マネージャーは、新しいドライバーのリゾルバーを簡単にマネージャへ登録できるように、extendメソッドを備えています。以降では、各カスタムドライバーのサポートを注入する例と一緒に、こうしたマネージャーを説明していきます。

Note: どうぞ時間を取り、CacheManagerSessionManagerのように、初めからLaravelに用意してある様々なManagerクラスを調べてみてください。こうしたクラスを徹底的に読めば、Laravelの内部動作を完全に理解することができます。全Managerクラスは、Illuminate\Support\Managerベースクラスを拡張しており、各Managerに共通で便利な機能を提供しています。

キャッシュ

Laravelのキャッシュ機能を拡張するには、CacheManagerextendメソッドを使用します。このメソッドはManagerへカスタムドライバーのリゾルバーを結合するために使用され、全Managerクラスで使用できます。例えば、"mongo"という名前のキャッシュドライバーを登録するには、次のようになります。

Cache::extend('mongo', function($app)
{
    return Cache::repository(new MongoStore);
});

extendメソッドの最初の引数は、ドライバーの名前です。この名前は、config/cache.php設定ファイルの中のdriverオプションと対応しています。2つ目の引数はクロージャーで、Illuminate\Cache\Repositoryインスタンスをリターンしなければなりません。クロージャーは、Illuminate\Foundation\Applicationのインスタンスであり、IoCコンテナでもある、$appインスタンスへ渡されます。

インストール後のLaravelアプリケーションに存在している、App\Providers\AppServiceProvider中のbootメソッドでCache::extendは呼び出される必要があります。もしくは拡張を記述するために独自のサービスプロバイダーを作成することもできます。その場合、config/app.phpのproviders配列へ指定するのを忘れないでください。

カスタムキャッシュドライバーを作成するには、Illuminate\Contracts\Cache\Store契約を実装する必要があります。ですから、MongoDBキャッシュの実装は、以下のようになるでしょう。

class MongoStore implements Illuminate\Contracts\Cache\Store {

    public function get($key) {}
    public function put($key, $value, $minutes) {}
    public function increment($key, $value = 1) {}
    public function decrement($key, $value = 1) {}
    public function forever($key, $value) {}
    public function forget($key) {}
    public function flush() {}

}

それぞれのメソッドをMongoDB接続を使用して実装する必要があります。実装を完了したら、カスタムドライバーの登録も完成させましょう。

Cache::extend('mongo', function($app)
{
    return Cache::repository(new MongoStore);
});

カスタムキャッシュドライバーコードをどこへ公開しようか迷っているなら、Packagistで使用できるようにすることを考えてください!もしくは、appディレクトリーの中にExtensions名前空間を作成することもできます。しかし、Laravelは厳格なアプリケーション構造を持っていないので、好みに合わせ、自由に構造を決めて良いことを覚えておきましょう。

セッション

Laravelにカスタムセッションドライバーを拡張するのは、キャッシュシステムを拡張するのと同様、簡単です。カスタムコードを登録するため、セッションでもextendメソッドを使用します。

Session::extend('mongo', function($app)
{
    // Return SessionHandlerInterfaceの実装を返す
});

セッションをどこで拡張するか

セッションの拡張は、AppServiceProviderbootメソッドの中へコードしましょう。

セッションの拡張をコーディングする

カスタムセッションドライバーはSessionHandlerInterfaceを実装する必要があることに注意してください。このインターフェイスは、実装する必要のあるシンプルないくつかのメソッドを含んでいます。MongoDB実装のスタブは、以下のようなコードになります。

class MongoHandler implements SessionHandlerInterface {

    public function open($savePath, $sessionName) {}
    public function close() {}
    public function read($sessionId) {}
    public function write($sessionId, $data) {}
    public function destroy($sessionId) {}
    public function gc($lifetime) {}

}

これらのメソッドは、キャシュのStoreInterfaceのように、簡単に理解できないため、それぞれのメソッドを簡単に解説しましょう。

SessionHandlerInterfaceを実装したら、セッションマネージャーに登録する準備ができました。

Session::extend('mongo', function($app)
{
    return new MongoHandler;
});

セッションドライバーを登録し終えたら、mongoドライバーをconfig/session.phpファイルで使用できます。

Note: カスタムセッションハンドラーを書いたら、Packagistで他の開発者と共有できることを思い出してください。

認証

キャッシュやセッション機能と同じ方法で、認証も拡張できます。既にお馴染みの、extendメソッドを今回も使用します。

Auth::extend('riak', function($app)
{
    // Return implementation of Illuminate\Contracts\Auth\UserProvider
});

UserProviderの実装は、Illuminate\Contracts\Auth\Authenticatable実装をMySQLやRiakなどの永続する保存システムから取得することだけに責任を持ちます。これらの2つのインターフェイスは、ユーザーデーターがどのように保存されているか、どのクラスがユーザーを表しているかにかかわらず、Laravel認証システムのメカニズムを機能させ続けてくれます。

UserProvider契約を見てみましょう。

interface UserProvider {

    public function retrieveById($identifier);
    public function retrieveByToken($identifier, $token);
    public function updateRememberToken(Authenticatable $user, $token);
    public function retrieveByCredentials(array $credentials);
    public function validateCredentials(Authenticatable $user, array $credentials);

}

retrieveById関数は、典型的にはMySQLデータベースの自動増加IDのような、ユーザーを表す数字キーを受け付けます。IDに一致するAuthenticatableの実装が取得され、メソッドにより返されます。

retrieveByToken関数は、一意の$identifierと、remember_tokenフィールドに保存されている"Remember me"トークンにより、ユーザーを取得します。前のメソッドと同様に、Authenticatableの実装をリターンしなくてはなりません。

updateRememberTokenメソッドは、$userremember_tokenフィールドを新しい$tokenで更新します。新しいトークンは"Remember me"によるログインが成功した時に生成される真新しいトークンでも良いですし、もしくはユーザーがログアウトした時はnullでもかまいません。

retrieveByCredentialsメソッドは、アプリケーションにログインするために、Auth::attemptメソッドに渡された、ログイン情報の配列を受け取ります。メソッドはユーザー情報に一致するユーザーが、裏にある持続的なストレージに存在しているか「クエリー」する必要があります。典型的にメソッドは、"where"条件で$credentials['username']のクエリーを実行することでしょう。このメソッドでパスワードのバリデーションや認証を試みてはいけません。

validateCredentialsメソッドは指定された$userとユーザーを認証するための$credentialsを比較する必要があります。例えば、このメソッドでは $user->getAuthPassword()文字列と、Hash::makeした$credentials['password']を比較する必要があるでしょう。

これでUserProviderのメソッドをそれぞれ学習し終えました。今度は、Authenticatableに注目していきましょう。プロバイダーはこのインターフェイスの実装をretrieveByIdretrieveByCredentialsメソッドから、返さなくてはならないことを覚えておいてください。

interface Authenticatable {

    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();

}

このインターフェイスはシンプルです。getAuthIdentifierメソッドは、そのユーザーの「主キー」を返さなくてはなりません。MySQLがバックエンドで使われているなら、ここでも自動増加主キーとなるでしょう。getAuthPasswordは、ユーザーのハッシュ済みのパスワードを返す必要があります。このインターフェイスにより、どんなORMやストレージの抽象クラスを使用してるのかに係わらず、認証システムをユーザークラスに対し動作させることを可能にしています。デフォルトでLaravelはこのインターフェイスを実装している、appディレクトリーの、Userクラスを含んでいます。ですから、実装のサンプルとして、このクラスを調べてみてください。

ついに、UserProviderを実装し、Authファサードへ拡張を登録する準備が整いました。

Auth::extend('riak', function($app)
{
    return new RiakUserProvider($app['riak.connection']);
});

ドライバーをextendメソッドで登録したら、config/auth.php設定ファイルでその新しいドライバーに切り替えましょう。

IoCベースの拡張

Laravelフレームワークに含まれている、ほとんどすべてのサービスプロバイダーは、IoCコンテナでオブジェクトを結合しています。config/app.php設定ファイルで、アプリケーションのサービスプロバイダーのリストを見つけられます。時間があれば、プロバイダーそれぞれのソースコードを拾い読みしてください。そうすれば、それぞれのプロバイダーがフレームワークに何を付け加えているのか、さらにIoCコンテナに数々のサービスを結合するため、どんなキーが使用されているか、もっと知ることができます。

例えば、HashServiceProviderは、IoCコンテナでhashキーと結合されており、Illuminate\Hashing\BcryptHasherインスタンスが依存解決されます。あなたは自分のアプリケーションの中でIoC結合をオーバーライドすることにより、簡単にクラスを拡張したり、オーバーライドしたりできます。例えば:

<?php namespace App\Providers;

class SnappyHashProvider extends \Illuminate\Hashing\HashServiceProvider {

    public function boot()
    {
        $this->app->bindShared('hash', function()
        {
            return new \Snappy\Hashing\ScryptHasher;
        });

        parent::boot();
    }

}

このクラスはベースクラスのデフォルトServiceProviderではなく、 HashServiceProvider を拡張していることに注意してください。サービスプロバイダーを拡張したら、config/app.php設定ファイルの中の、HashServiceProviderをあなたが拡張したプロバーダー名へ交換してください。

ここまでコンテナで結合されたコアクラスを拡張する、一般的な方法を見てきました。基本的に、コンテナ上の全てのコアクラスは、こうした方法で結合されており、オーバーライド可能です。繰りかえしますが、フレームワークに含まれているサービスプロバイダーを全般的に読んでみてください。様々なクラスに親しめますし、どのキーで結合されているか分かります。これは、Laravelがどのように一つにまとめられているのかを詳しく理解できる、素晴らしい方法です。

ドキュメント章別ページ

Artisan CLI

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる