Readouble

Laravel master 契約

イントロダクションIntroduction

Laravelの契約とはインターフェイスのことで、フレームワークにより提供されているコアサービスを定義したものです。例えばIlluminate\Contracts\Queue\Queue契約はジョブをキューするために必要なメソッドを定義しており、一方Illuminate\Contracts\Mail\Mailer契約はメール送信に必要なメソッドを定義しています。Laravel's Contracts are a set of interfaces that define the core services provided by the framework. For example, a Illuminate\Contracts\Queue\Queue contract defines the methods needed for queueing jobs, while the Illuminate\Contracts\Mail\Mailer contract defines the methods needed for sending e-mail.

それぞれの契約はフレームワークにより提供されている実装と対応しています。たとえばLaravelは多様なドライバと共に、キューの実装を提供しており、メーラーの実装は、SwiftMailerです。Each contract has a corresponding implementation provided by the framework. For example, Laravel provides a queue implementation with a variety of drivers, and a mailer implementation that is powered by SwiftMailer[http://swiftmailer.org/].

Laravelの全契約はGitHubのリポジトリーで参照できます。これは全契約を素早く参照する方法であり、同時にパッケージ開発者は個別に独立したパッケージを利用する際、参考にできるでしょう。All of the Laravel contracts live in their own GitHub repository[https://github.com/illuminate/contracts]. This provides a quick reference point for all available contracts, as well as a single, decoupled package that may be utilized by package developers.

契約 Vs. FacadesContracts Vs. Facades

Laravelのファサードとヘルパ関数は、タイプヒントやサービスコンテナを契約の解決に使用する必要なく、Laravelの機能を活用できる、シンプルな手法を提供しています。ほとんどの場合、各ファサードと同等の契約が用意されています。Laravel's facades[/docs/{{version}}/facades] and helper functions provide a simple way of utilizing Laravel's services without needing to type-hint and resolve contracts out of the service container. In most cases, each facade has an equivalent contract.

クラスのコンストラクタで、タイプヒントを指定する必要がないファサードと異なり、契約はクラスで必要な依存を明確に定義付けることができます。ある開発者はこの方法で、明確に依存を定義することを好みますが、一方で他の開発者はファサードの利便性を楽しんでいます。Unlike facades, which do not require you to require them in your class' constructor, contracts allow you to define explicit dependencies for your classes. Some developers prefer to explicitly define their dependencies in this way and therefore prefer to use contracts, while other developers enjoy the convenience of facades.

lightbulb">Tip!! 大抵のアプリケーションでは、好みがファサードでも、契約でも問題ないでしょう。しかし、パッケージを作成する場合は、パッケージ開発のテストのしやすさという点で、契約を使うことをしっかりと考えるべきでしょう。{tip} Most applications will be fine regardless of whether you prefer facades or contracts. However, if you are building a package, you should strongly consider using contracts since they will be easier to test in a package context.

いつ契約を使うかWhen To Use Contracts

他でも説明しているように、契約とファサードのどちらを使うかは、個人や開発チームの好みに行き着きます。契約とファサードのどちらでも、堅牢でよくテストされたLaravelアプリケーションを作成できます。クラスの責務に焦点を当てていれば、契約とファサード間の実践上の違いはとても小さいことに気がつくでしょう。As discussed elsewhere, much of the decision to use contracts or facades will come down to personal taste and the tastes of your development team. Both contracts and facades can be used to create robust, well-tested Laravel applications. As long as you are keeping your class' responsibilities focused, you will notice very few practical differences between using contracts and facades.

However, you may still have several questions regarding contracts. For example, why use interfaces at all? Isn't using interfaces more complicated? Let's distil the reasons for using interfaces to the following headings: loose coupling and simplicity.However, you may still have several questions regarding contracts. For example, why use interfaces at all? Isn't using interfaces more complicated? Let's distil the reasons for using interfaces to the following headings: loose coupling and simplicity.

疎結合Loose Coupling

最初にキャッシュの実装とがっちり結合したコードをレビューしてみましょう。次のコードをご覧ください。First, let's review some code that is tightly coupled to a cache implementation. Consider the following:

<?php

namespace App\Orders;

class Repository
{
    /**
     * キャッシュインスタンス
     */
    protected $cache;

    /**
     * 新しいリポジトリインスタンスの生成
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * 注文をIDから取得
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}

このクラスのコードは、使用しているキャッシュの実装ときつく結合しています。つまりパッケージベンダーの具象キャッシュクラスに依存しているために、結合が強くなっています。パッケージのAPIが変更されたら、同時にこのコードも変更しなくてはなりません。In this class, the code is tightly coupled to a given cache implementation. It is tightly coupled because we are depending on a concrete Cache class from a package vendor. If the API of that package changes our code must change as well.

キャッシュの裏で動作している技術(Memcached)を別のもの(Redis)へ置き換えたくなれば、リポジトリーを修正する必要があるというのは起こり得ます。リポジトリーは誰がデータを提供しているかとか、どのように提供しているかという知識を沢山持っていてはいけません。Likewise, if we want to replace our underlying cache technology (Memcached) with another technology (Redis), we again will have to modify our repository. Our repository should not have so much knowledge regarding who is providing them data or how they are providing it.

このようなアプローチを取る代わりに、ベンダーと関連がないシンプルなインターフェイスへ依存するコードにより向上できます。Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository
{
    /**
     * キャッシュインスタンス
     */
    protected $cache;

    /**
     * 新しいリポジトリインスタンスの生成
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

これでコードは特定のベンダー、しかもLaravelにさえ依存しなくなりました。契約パッケージは実装も依存も含んでいないため、与えられた契約の異なった実装を簡単に記述できます。キャッシュを使用するコードを変更することなく、キャッシュ実装を置き換えることができるようになりました。Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code.

単純さSimplicity

Laravelのサービスは全てシンプルなインターフェイスの中で適切に定義されているので、サービスが提供する機能も簡単に定義できています。 契約はフレームワークの機能の簡単なドキュメントとして使えます。When all of Laravel's services are neatly defined within simple interfaces, it is very easy to determine the functionality offered by a given service. The contracts serve as succinct documentation to the framework's features.

それに加え、シンプルなインターフェイスに基づけばあなたのコードは簡単に理解でき、メンテナンスできるようにもなります。大きくて複雑なクラスの中でどのメソッドが使用可能かを探し求めるよりも、シンプルでクリーンなインターフェイスを参照できます。In addition, when you depend on simple interfaces, your code is easier to understand and maintain. Rather than tracking down which methods are available to you within a large, complicated class, you can refer to a simple, clean interface.

契約使用法How To Use Contracts

では、契約の実装はどうやって入手するのでしょうか?とてもシンプルです。So, how do you get an implementation of a contract? It's actually quite simple.

Laravelでは多くのタイプのクラスがサービスコンテナを利用して依存解決されています。コントローラーを始め、イベントリスナ、フィルター、キュージョブ、それにルートクロージャもそうです。契約の実装を手に入れるには、依存を解決するクラスのコンストラクターで「タイプヒント」を指定するだけです。Many types of classes in Laravel are resolved through the service container[/docs/{{version}}/container], including controllers, event listeners, middleware, queued jobs, and even route Closures. So, to get an implementation of a contract, you can just "type-hint" the interface in the constructor of the class being resolved.

例として、次のイベントハンドラをご覧ください。For example, take a look at this event listener:

<?php

namespace App\Listeners;

use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;

class CacheOrderInformation
{
    /**
     * Redisデータベースの実装
     */
    protected $redis;

    /**
     * 新しいイベントハンドラの生成
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * イベントの処理
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */
    public function handle(OrderWasPlaced $event)
    {
        //
    }
}

イベントリスナの依存解決時に、サービスコンテナはクラスのコンストラクターで指定されているタイプヒントを読み取り、適切な値を注入します。サービスコンテナへ何かを登録する方法を学ぶには、ドキュメントを参照してください。When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out its documentation[/docs/{{version}}/container].

契約リファレンスContract Reference

次の一覧表は、全Laravel契約と、同機能のファサードのクイックリファレンスです。This table provides a quick reference to all of the Laravel contracts and their equivalent facades:

契約Contract 対応するファサードReferences Facade
Illuminate\Contracts\Auth\FactoryIlluminate\Contracts\Auth\Factory[https://github.com/illuminate/contracts/blob/master/Auth/Factory.php] AuthAuth
Illuminate\Contracts\Auth\PasswordBrokerIlluminate\Contracts\Auth\PasswordBroker[https://github.com/illuminate/contracts/blob/master/Auth/PasswordBroker.php] PasswordPassword
Illuminate\Contracts\Bus\DispatcherIlluminate\Contracts\Bus\Dispatcher[https://github.com/illuminate/contracts/blob/master/Bus/Dispatcher.php] BusBus
Illuminate\Contracts\Broadcasting\BroadcasterIlluminate\Contracts\Broadcasting\Broadcaster[https://github.com/illuminate/contracts/blob/master/Broadcasting/Broadcaster.php]   
Illuminate\Contracts\Cache\RepositoryIlluminate\Contracts\Cache\Repository[https://github.com/illuminate/contracts/blob/master/Cache/Repository.php] CacheCache
Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Factory[https://github.com/illuminate/contracts/blob/master/Cache/Factory.php] Cache::driver()Cache::driver()
Illuminate\Contracts\Config\RepositoryIlluminate\Contracts\Config\Repository[https://github.com/illuminate/contracts/blob/master/Config/Repository.php] ConfigConfig
Illuminate\Contracts\Container\ContainerIlluminate\Contracts\Container\Container[https://github.com/illuminate/contracts/blob/master/Container/Container.php] AppApp
Illuminate\Contracts\Cookie\FactoryIlluminate\Contracts\Cookie\Factory[https://github.com/illuminate/contracts/blob/master/Cookie/Factory.php] CookieCookie
Illuminate\Contracts\Cookie\QueueingFactoryIlluminate\Contracts\Cookie\QueueingFactory[https://github.com/illuminate/contracts/blob/master/Cookie/QueueingFactory.php] Cookie::queue()Cookie::queue()
Illuminate\Contracts\Encryption\EncrypterIlluminate\Contracts\Encryption\Encrypter[https://github.com/illuminate/contracts/blob/master/Encryption/Encrypter.php] CryptCrypt
Illuminate\Contracts\Events\DispatcherIlluminate\Contracts\Events\Dispatcher[https://github.com/illuminate/contracts/blob/master/Events/Dispatcher.php] EventEvent
Illuminate\Contracts\Filesystem\CloudIlluminate\Contracts\Filesystem\Cloud[https://github.com/illuminate/contracts/blob/master/Filesystem/Cloud.php]   
Illuminate\Contracts\Filesystem\FactoryIlluminate\Contracts\Filesystem\Factory[https://github.com/illuminate/contracts/blob/master/Filesystem/Factory.php] FileFile
Illuminate\Contracts\Filesystem\FilesystemIlluminate\Contracts\Filesystem\Filesystem[https://github.com/illuminate/contracts/blob/master/Filesystem/Filesystem.php] FileFile
Illuminate\Contracts\Foundation\ApplicationIlluminate\Contracts\Foundation\Application[https://github.com/illuminate/contracts/blob/master/Foundation/Application.php] AppApp
Illuminate\Contracts\Hashing\HasherIlluminate\Contracts\Hashing\Hasher[https://github.com/illuminate/contracts/blob/master/Hashing/Hasher.php] HashHash
Illuminate\Contracts\Logging\LogIlluminate\Contracts\Logging\Log[https://github.com/illuminate/contracts/blob/master/Logging/Log.php] LogLog
Illuminate\Contracts\Mail\MailQueueIlluminate\Contracts\Mail\MailQueue[https://github.com/illuminate/contracts/blob/master/Mail/MailQueue.php] Mail::queue()Mail::queue()
Illuminate\Contracts\Mail\MailerIlluminate\Contracts\Mail\Mailer[https://github.com/illuminate/contracts/blob/master/Mail/Mailer.php] MailMail
Illuminate\Contracts\Queue\FactoryIlluminate\Contracts\Queue\Factory[https://github.com/illuminate/contracts/blob/master/Queue/Factory.php] Queue::driver()Queue::driver()
Illuminate\Contracts\Queue\QueueIlluminate\Contracts\Queue\Queue[https://github.com/illuminate/contracts/blob/master/Queue/Queue.php] QueueQueue
Illuminate\Contracts\Redis\DatabaseIlluminate\Contracts\Redis\Database[https://github.com/illuminate/contracts/blob/master/Redis/Database.php] RedisRedis
Illuminate\Contracts\Routing\RegistrarIlluminate\Contracts\Routing\Registrar[https://github.com/illuminate/contracts/blob/master/Routing/Registrar.php] RouteRoute
Illuminate\Contracts\Routing\ResponseFactoryIlluminate\Contracts\Routing\ResponseFactory[https://github.com/illuminate/contracts/blob/master/Routing/ResponseFactory.php] ResponseResponse
Illuminate\Contracts\Routing\UrlGeneratorIlluminate\Contracts\Routing\UrlGenerator[https://github.com/illuminate/contracts/blob/master/Routing/UrlGenerator.php] URLURL
Illuminate\Contracts\Support\ArrayableIlluminate\Contracts\Support\Arrayable[https://github.com/illuminate/contracts/blob/master/Support/Arrayable.php]   
Illuminate\Contracts\Support\JsonableIlluminate\Contracts\Support\Jsonable[https://github.com/illuminate/contracts/blob/master/Support/Jsonable.php]   
Illuminate\Contracts\Support\RenderableIlluminate\Contracts\Support\Renderable[https://github.com/illuminate/contracts/blob/master/Support/Renderable.php]   
Illuminate\Contracts\Validation\FactoryIlluminate\Contracts\Validation\Factory[https://github.com/illuminate/contracts/blob/master/Validation/Factory.php] Validator::make()Validator::make()
Illuminate\Contracts\Validation\ValidatorIlluminate\Contracts\Validation\Validator[https://github.com/illuminate/contracts/blob/master/Validation/Validator.php]   
Illuminate\Contracts\View\FactoryIlluminate\Contracts\View\Factory[https://github.com/illuminate/contracts/blob/master/View/Factory.php] View::make()View::make()
Illuminate\Contracts\View\ViewIlluminate\Contracts\View\View[https://github.com/illuminate/contracts/blob/master/View/View.php]   

章選択

開発環境
ビューとテンプレート
公式パッケージ

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作