LoginSignup
22
24

More than 5 years have passed since last update.

laravel5.2のスタートアッププラクティス

Last updated at Posted at 2016-04-28

Laravel5で開発を始める前に行っていることをまとめました。
各設定ファイルのディレクトリ構成のカスタマイズや、Laravelを拡張するためのコードの配置場所を設定しています。
この方法がスタンダードということはありませんが、開発チームで予め標準化しておくと、保守性も向上するのではないでしょうか。
ここではデータベースのマイグレーションやカスタムミドルウェアの設定、Javascript/CSSのビルドなどは割愛しています。

環境

  • OS: osx10.11.4
  • PHP: PHP5.6.x
  • Laravel: 5.2.31

Laravelインストール

現時点では、5.2.31がリリースされています。

$ composer create-project --prefer-dist laravel/laravel
$ cd laravel
$ ./artisan --version
Laravel Framework version 5.2.31

gitリポジトリ作成

gitリポジトリを作成します。

$ git init
$ git add .
$ git commit -m 'initial commit'

動作確認

簡単に動作を確認します。
実際の開発時も、PHPビルトインサーバを利用することが多いです。なんといっても手軽です。

$ php -S 0.0.0.0:8080 -t public/

もちろん、Vagrantでステージングサーバを構築して、試験することも併用しています。
また、プロダクションサーバへのデプロイメントもVagrantで作成したステージングサーバで調整・検証しています。
プロビジョニングには、Ansibleを利用しています。
今後は、LaravelアプリもDockerコンテナ化して、瞬時にデプロイできるように考えています。

プロジェクトネームスペースの定義

プロジェクトの固有のソースコードの配置先を変更し、ネームスペースを分離しています。
まず、プロジェクトのソースコードディレクトリを作成します。
ここではHttpディレクトリだけ作成していますが、概ねLaravelのapp/のディレクトリ構成をそのまま、プロジェクトのネームスペースで作成しています。
editorはお好きなものに置き換えてください。筆者は、atomエディタで開発しています。

ディレクトリを作成したらpsr4でオートロードできるようにcomposer.jsonに追加します。

$ mkdir -p srcs/app/Http
composer.json

"autoload": {
  "classmap": [
    "database"
  ],
  "psr-4": {
    "App\\": "app/",
    "Project\\": "srcs/app/"
  }
},

その後、オートロードファイルを再生成します。

$ composer dump-autoload
Generating autoload files

autoload_classmap.phpを参照すれば、追加されていることが確認できます。

/vendor/composer/autoload_classmap.php

'Project\\' => array($baseDir . '/srcs/app'),

routes.phpの移動

通常、app/Http/routes.phpに配置されていますが、よく参照・変更するファイルなので、プロジェクトのHttpへ移動します。
好みの問題でもありますから、必須というわけではありません。

$ cp app/Http/routes.php srcs/app/Http
app/Providers/RouteServiceProvider.php
protected function mapWebRoutes(Router $router)
{
  $router->group([
    'namespace' => $this->namespace, 'middleware' => 'web',
  ], function ($router) {
    // require app_path('Http/routes.php'); routes.phpのロケーションを変更します。
    require base_path('srcs/app/Http/routes.php');
  });
}

コンフィグレーションの設定

日本語ファイルを英語のものから作成しておきます。多国語対応する必要がなくても、メッセージの保守性を向上するために言語ファイルに全てのメッセージを定義しています。

$ cp -a resources/lang/en resources/lang/ja

次に、アプリケーションのコンフィグレーションを設定します。
url、タイムゾーン、ロケールの設定とプロジェクト固有のサービスプロバイダを一つ以上設定しています。

config/app.php
'url' => 'http://www.project.com',
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'fallback_locale' => 'ja',

'providers' => [
...
     Project\Providers\AppServiceProvider::class,
]

サービスプロバイダの定義

プロジェクト固有のサービスプロバイダには、ストレージパスの設定や、bladeで利用するカスタムなディレクティブ、フォームバリデーションで利用する共通のバリデータなどを定義しています。
まず、bootメソッドでストレージパスを変更しています。いままではシンボリックリンクでデプロイごとのストレージが変わらないようしていましたが、今後Dockerコンテナ化も考慮して、任意のパスに変更するようにしました。

注記

このタイミングでstorage_path()を変更しても、storage/framework/{cache,sessions,views},storage/logsのパスには反映されないことがわかりました。
適切かどうか不明ですが、bootstrap/app.php$appを返す前に、$app->useStoragePath('/tmp/storage')してやると反映されました。

その後、Bladeのカスタムディレクティブやカスタムバリデータを定義しています。数が多くなれば、それぞれ別のプライベートメソッドへ移動したり、別のサービスプロバイダを作成します。
サンプルとして、日付をフォーマットするディレクティブ、電話番号をバリデートするものを用意しました。

registerメソッドでは、サービスインタフェースに対して、DI(Dependency Injection)したいクラスを設定しています。コントローラのコンストラクタの引数にインタフェースをタイプヒンティングしておけば、ここでbindされたクラスインスタンスが自動的にインジェクションされます(コンストラクタインジェクション)。

$ mkdir srcs/app/Providers
srcs/app/Providers/ServiceProvider.php
<?php namespace Project\Providers;

use Blade;
use Validator;
use Log;
use Input;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
  /**
   * Bootstrap any application services.
   *
   * @return void
   */
  public function boot()
  {
    app()->useStoragePath('/tmp/storage');

    Blade::directive('date', function($expression) {
      return "$expression ? (new DateTime{$expression})->format('Y/m/d') : trans('app.none')";
    });

    Validator::extend('tel', function($attribute, $value, $parameters, $validator) {
      $value = mb_convert_kana($value, 'n', 'utf-8');
      return preg_match("/^[0-9]+$/u", $value);
    });

  }

  /**
   * Register any application services.
   *
   * This service provider is a great spot to register your various container
   * bindings with the application. As you can see, we are registering our
   * "Registrar" implementation here. You can add your own bindings too!
   *
   * @return void
   */
  public function register()
  {
    $this->app->bind(
      \Project\Services\ServiceContract::class, \Projet\Services\Service::class
    );
  }

}
srcs/app/Controller/Service.php
public function __construct(ServiceContract $service) // Serviceクラスのインスタンスがインジェクトされる。
{
  $this->service = $service;
}

ストレージパスが変更できているかtinkerで確認します。
tinkerはREPL(Read-Eval-Print Loop)と呼ばれるインタラクティブシェルのようなものです。Laravel環境で、小さなコードをインタラクティブに動作させることができます。ちょっとしたデバッグやテストに最適で便利です。

$ ./artisan tinker
Psy Shell v0.7.2 (PHP 5.6.19 — cli) by Justin Hileman
>>> storage_path()
=> "/tmp/storage"
>>>

個人的な小さなプロジェクトなら、直接app/にファイルを追加していってもよいのですが、チームで継続して開発するなら、予めこのようなプラクティスを決めておくと、開発効率や保守性が向上するのではないでしょうか。何かの参考になれば、幸いです。

22
24
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
22
24