36
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravel5でヘルパーメソッドを実装してみた

Last updated at Posted at 2015-03-22

はじめに

ドキュメントやコード読んだりしながら分かったことをまとめました。
URLをよしなに生成してくれる便利なassetというヘルパーメソッドがあるので、
これを試しにちょっとカスタマイズしてみたいと思います。

作ってみる

メソッドを実装したphpファイルを作ってrequireします。では順を追って説明します。
(requireする以外にcomposerを利用する方法も試したので、そちらもチョロっと紹介したいとます。)

helpers.php

僕の場合はHelpersというディレクトリを作って、その下にhelpers.phpというのを書きました。

app/Helpers/helpers.php
<?php

if ( ! function_exists('assetEx'))
{
  /**
   * assetの処理に加えて、ランダムな値をクエリストリングとして付加する。
   *
   * @param  string  $file
   * @param  bool    $secure
   * @return string
   */
  function assetEx($file, $secure = false)
  {
      static $refresher = null;

      if (is_null($refresher))
      {
        $refresher = mt_rand();
      }
      return app('url')->asset($file, $secure) . '?' . $refresher;
  }
}

1ここで紹介する例はぜーんぜん実用的ではないのでご注意ください。

requireする

僕はとりあえず public/index.phpでautoloadしている手前でさっき作ったhelpers.phpをrequireしました。
(追記:ここだとユニットテスト走らせるときとか読み込んでくれないのでbootstrap/index.phpのほうが良いと同僚に指定されました。なるほど確かに!)

public/index.php

    << 省略 >>
/*
|--------------------------------------------------------------------------
| Register The Original Auto Loader
|--------------------------------------------------------------------------
*/

require __DIR__.'/../app/Helpers/helpers.php';


/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels nice to relax.
|
*/

require __DIR__.'/../bootstrap/autoload.php';

    << 省略 >>

ちなみにLaravelで実装されているヘルパーと同名のメソッドを作りたい場合はautoload前でrequireする必要があります。

使う

こんな感じで使えるようになります。

テンプレート

<img src="{{ assetEx("hoge.jp/fuga.png") }}">

生成されるHTML

<img src="http://hoge.jp/fuga.png?3801342084329384">

requireじゃなくてcomposerを使う

別の方法としてcomposerで読み込む方法もあります。requireするのとどっちがスマートかは運用ポリシーとかで変わってくると思うので、よく考えて選択したいところです。

composer.json のautoload下にfilesとして指定します。

composer.json
  <<省略>>
    "autoload": {
        "classmap": [
            "database"
        ],
        "files": [
            "app/Helpers/helpers.php"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
  <<省略>>

そしたらcomposer update!

$ composer update app/Helpers/helpers.php

これでrequireしたときと同じように使えるようになります。

ヘルパークラスを作る

ヘルパーメソッドを実装するのは簡単なんですが、クラスじゃないからテストが書きづらいんですよね。
実際Laravelで実装されているヘルパーを見てみると、メソッド自体は非常にシンプルになっていました。
デフォルトでこの2ファイルがcomposerで読み込まれています。
・vendor/laravel/framework/src/Illuminate/Support/helpers.php
・vendor/laravel/framework/src/Illuminate/Foundation/helpers.php

ヘルパーメソッドをシンプルに

というわけで、僕もヘルパーメソッド自体はシンプルにしたい。
こんな感じにします。

app/Helpers/helpers.php
<?php

if ( ! function_exists('assetEx'))
{
  /**
   * assetの処理に加えて、ランダムな値をクエリストリングとして付加する。
   *
   * @param  string  $file
   * @param  bool    $secure
   * @return string
   */
  function assetEx($file, $secure = false)
  {
    return app('AppUrl')->assetEx($file, $secure);
  }
}

ヘルパークラスを実装する

assetが実装されているクラス名をパクってUrlGeneratorというクラスを作ります。

app/Helpers/UrlGenerator.php
<?php namespace App\Helpers;

class UrlGenerator {

  /**
   * assetの処理に加えて、ランダムな値をクエリストリングとして付加する。
   *
   * @param  string  $path
   * @param  bool  $secure
   * @return string
   */
  public function assetEx($path, $secure = false)
  {
      static $refresher = null;

      if (is_null($refresher))
      {
        $refresher = mt_rand();
      }
      return app('url')->asset($path, $secure) . '?' . $refresher;
  }
}

aliasesの設定

ヘルパーメソッドにて app('AppUrl') って感じでクラスを呼び出すには config/app.php の aliases にこんな感じで追記します。

config/app.php
  'aliases' => [

    << 省略 >>

    'AppUrl'    => 'App\Helpers\UrlGenerator',
  ],

以上、ヘルパーの実装方法でした!

まとめ

ヘルパーメソッドの実装自体は大したことなかったんですが、ユニットテストを書くためにLaravelのFacadeあたりのソースを追ったりは僕には大変でした。(テストの書き方については後日またまとめたい)
でもおかげでファサードパターンというデザパタを知る機会にもなって面白かったです。

  1. 実際にはproductionやdevelopなど、環境によって参照先を変えたりランダムなクエリストリングもリクエスト毎で変わるのではなくElixirちっくにしたりしました。

36
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?