カテゴリーアーカイブ FuelPHP

著者:杉浦

【PHP】DI(依存性注入)を用いたコードの追い方

 DI(Dependency injection)(依存性注入)とはコード内で外部への依存を直書きするのでなく、外部から引数、セッターなどで依存する部分を与える実装のことです。例えば、次です。

use Illuminate\Contracts\Hashing\Hasher as HasherContract;

class DatabaseUserProvider implements UserProvider
{
    /**
     * The hasher implementation.
     *
     * @var \Illuminate\Contracts\Hashing\Hasher
     */
    protected $hasher;

    /**
     * Create a new database user provider.
     *
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @return void
     */
    public function __construct(HasherContract $hasher)
    {
        $this->hasher = $hasher;
    }
    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        return $this->hasher->check(
            $credentials['password'], $user->getAuthPassword()
        );
    }
}

 DatabaseUserProviderクラスがインスタンス化された際にHasherContract型の引数$hasherを要求し、$hasherを保持します。保持した$hasherをvalidateCredentialsメソッド内で用います。
 外部から依存するモノを与えるため、テストし易かったり変更し易かったりするのですが、あまりに自由で今稼働しているコードでは何が実体化しているのかわかりにくく、追うのが少し難しいです。上記コードなら$this->hasherって何?となってIDEの機能で型を追ってもHasherContractというインターフェースが現れて終わりです。HasherContractを満たすどのHasherクラスが使われているか分かりません。
 hasherの中身、ひいては実際の動作を知りたい時は、まず依存性が実際に注入された際のコードを動かし、その時のhasherの中身に何が入ってるのか調べる必要があります。PHPならば次の様に出来ます。

    public function __construct(HasherContract $hasher)
    {
        var_dump(get_class($hasher));exit;
        $this->hasher = $hasher;
    }

PHP: get_class – Manual
 get_class関数でインスタンスそのものに、あなたのクラス名は何ですか、と尋ねます。得られたクラス名が今稼働しているシステムで注入されているクラスの名前です。例えば、ここでBcryptHasherという実装クラスが呼ばれているとわかったら次の様に型付けをします。

class DatabaseUserProvider implements UserProvider
{
    /**
     * The hasher implementation.
     *
     * @var \Illuminate\Hashing\BcryptHasher
     */
    protected $hasher;

    /**
     * Create a new database user provider.
     *
     * @param  \Illuminate\Hashing\BcryptHasher  $hasher
     * @return void
     */
    public function __construct(BcryptHasher $hasher)
    {
        $this->hasher = $hasher;
    }
    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        return $this->hasher->check(
            $credentials['password'], $user->getAuthPassword()
        );
    }
}

 こうするとIDEのジャンプ機能はインターフェースHasherContractでなくクラスBcryptHasherを参照するようになり、静的にコードを追うことが格段に楽になります。注意点として直し忘れがあります。DIを駆使したコードほど直し忘れると型エラーで派手に事故ります。

  • この記事いいね! (1)
takahashi 著者:takahashi

FuelPHPで今開いているページのコントローラー/アクションを取得する方法

・コントローラー名を取得したいとき(コントローラークラス名)

echo Request::main()->controller;
//ex.: Controller_Hogehoge

・アクション名を取得したいとき

echo Request::active()->action:
//ex.: huga

なお、コントローラーを取る方法として、Uriクラスを使って

 echo Request::main()->uri->segment(1);  //ベースURLから1番目の値をとる

とすることもできるようですが、index(/)などの場合、取得できる値がNULLになってしまう問題があるため、個人的には最初の方法で取得したうえで正規表現などで加工した方が確実かな、と思います。

参考:
[PHP][FuelPHP]FuelPHPで気になるあの情報の取り出し方 – ECサイト運営開発記

  • この記事いいね! (0)