1. mikakane

    No comment

    mikakane
Changes in body
Source | HTML | Preview

laravel謹製のマイクロフレームワーク lumenが出たので使ってみた。
ざっくり触りながらのまとめになりますが、ツッコミポイントとかアレば是非コメントお願いしまっす。

インストール

laravelとは別のインストーラなので新規にComposer経由でグローバルインストール。

$ composer global require "laravel/lumen-installer=~1.0"
$ lumen new service
$ cd service
$ php artisan serve

http://localhost:8000でキレイに繋がります。

設定とか

Dotenv形式の設定がベースになっているっぽいけど、
bootstrap/app.php を見ると、Dotenv::loadはデフォルトでコメントアウトされている。
基本の設定をコピーしてからアンコメントすると、キレイに読み込まれる。

ベースはproductionモードでエラー詳細とか見れないので、困ったときはこれで。

別ファイルからの設定とかも読み込めるみたいだけど後で。

概要

基本はbootstrap/app.phpが兎に角がんばるみたいな形式っぽい。
.envの設定ファイルとbootstrap/app.phpだけでアプリケーションを組み立てて行く。

index.phpはというと、bootstrap/app.phpからオブジェクトを受け取ってrun()するだけ。すっごくシンプル。

bootstrap/app.php

1 Composer/Dotenvの読み込み

require_once __DIR__.'/../vendor/autoload.php';

//Dotenv::load(__DIR__.'/../');

アプリケーションごとComposerに突っ込む時はComposerの読み込みは不要。Dotenvはデフォルトでコメントアウトされてるので必要がアレば外す。

2 Applicationオブジェクトの作成

$app = new Laravel\Lumen\Application;

// $app->withFacades();

// $app->withEloquent();

ファザードとかEloquentとか使いたい人はコメント外せばイイ。

3 implement実装の登録

例外ハンドラとタスクカーネルは必須っぽい。
スケルトンにあるAppとかを使ってとりあえず実装を登録しておく。

$app->singleton(
    'Illuminate\Contracts\Debug\ExceptionHandler',
    'App\Exceptions\Handler'
);

$app->singleton(
    'Illuminate\Contracts\Console\Kernel',
    'App\Console\Kernel'
);

4 ミドルウェアの登録

デフォルトでは全部コメントアウトされてる。middlewareメソドやrouteMiddlewareメソドが使える。

// $app->middleware([
//     // 'Illuminate\Cookie\Middleware\EncryptCookies',
//     // 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
//     // 'Illuminate\Session\Middleware\StartSession',
//     // 'Illuminate\View\Middleware\ShareErrorsFromSession',
//     // 'Laravel\Lumen\Http\Middleware\VerifyCsrfToken',
// ]);

// $app->routeMiddleware([
// ]);

5 サービス・プロバイダの登録

こちらもコメントアウトされてる。デフォルト登録のコンテナはここになくて、後述のavailableBindingsに処理が記述されてる。lumenならではのコンテナ取り出しバインディングを使いたい場合は後述のavailableBindingsを使えばイイ。

// $app->register('App\Providers\AppServiceProvider');

6 ルートの読み込み

ルートファイルの読み込み。ファイルベースが嫌ならコメントアウトして、サービス・プロバイダとかに突っ込めばいいと思うよ。

require __DIR__.'/../app/Http/routes.php';

7 お返し

ファイルベースで処理するのが嫌なら1-6までまとめて$appオブジェクトをreturnするクラスを作ればいいです(そのほうが可搬性も良さそう)。

return $app;

設定周り

Application クラスのプロパティで色々制御できる。

protected $basePath

ベースパス。色々なパスの計算の起点になる。

base_path()関数で値が取れます。

protected $storagePath

storage ディレクトリの置き場所
ログとかがここに入る。

storage_path()関数で値が取れます。

protected $configPath

config ディレクトリの置き場所

protected $resourcePath

resource ディレクトリの置き場所

この扱いはホントに微妙で、早い話がlangでしかここの設定は使われてない。というのもbase_path()とかstorage_path()とかその辺の関数は用意されてんのに、resource_path()は用意されれなくてグローバルに参照出来ない。

langtranslatorサービスの登録フックで使われているのでApplicationクラスからの内部参照で使われてるけどviewsの方はConfigファイルでのパス指定になるのでやむなくbase_path("resource/views")とかしてる。

translator使わなければ別にここの値は無視してもいいし、ここの値をどうこうしてもviewサービスのパスは変更できない。

public $availableBindings

デフォルトサービスの登録処理一覧。詳細はこっち

routing

ルートはapp/Http/routes.phpに書く。

形式はシンプルになっててsilexみたいな感じ。ただcontroller系のあれがいろいろなくって、implict controllerすら使えないっぽいので困った。

クラス化したコントローラで使えるのは、こんな感じの@系ルートだけ?

$app->get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

コンストラクタの自動注入が使える位の恩恵?とおもうと微妙な所。

ただルートに正規表現っぽいのが使えるのは嬉しい。
http://lumen.laravel.com/docs/routing

laravelにはない機能なので、lumenからlaravelに移行する時には注意、ってドキュメントにも書いてある。

require読み込みでヤルのがいやなら、サービスプロバイダとか。

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

/**
 * アプリ側のルーティングを記述
 * @package App\Providers
 */
class AppRoutesServiceProvider extends ServiceProvider
{

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $app = $this->app;
        $this->app->get('', function()use($app) {
            return $app->welcome();
        });
    }
}

デフォルト画面で表示されるwelcom画面は、lumenが コアで 持っているwelcomeメソド生成しているHTMLコードです。

すっごい不思議なのが、クロージャの中の$thisLaravel\Lumen\Routing\Closureになる。PHPのクロージャの$thisってそんな感じでしたっけ?

溢れてくるアクションの取りまとめをどーするか悩みに悩んだ結果、Controller側でstaticにregisterメソドを持たせる方向でとりあえず。

<?php namespace App\Http\Controllers;
use Laravel\Lumen\Application;

class AccountController extends AppController {

    static public function register(Application $app)
    {
        $app->group(["namespace"=>'App\Http\Controllers'],function(Application $app){
            $app->get("account/login","AccountController@getLogin");
            $app->get("account/logout","AccountController@getLogout");
        });
    }

    public function getLogin(){
        return view("account/login");
    }
    public function getLogout(){
        return view("account/logout");
    }
}

// route.php
AccountController::register($app);

あんまりキレイな気もしない。
ちなみに、ルートにcallableを採用するsilexとは違い、lumenでは厳密にClousureを取るので、[$this,"methodName"]みたいな書き方は出来ない。

せめてsilexのmountみたいなのアレばいいけど。

ちょっと特殊なルーティング問題

手許のPHPビルトインサーバで試してみたところ、
インデックスファイルをルートのindex.phpにした場合、例えばpublic/api/index.phpみたいなファイルを置いた場合、
ルート文字列のマッチが/apiからスタートする。インデックスファイルを変更するのはあまりオススメ出来ないのかも。