silex

PHPのマイクロフレームワークSilexを触ってみました。

最小のアプリケーション

SilexはComposerでインストールできます。プロジェクト用のディレクトリを作成し、composer.jsonを作成します。

{
    "require": {
        "php": ">=5.3.3",
        "silex/silex": "~1.2"
    }
}
% composer install

web/index.phpを作成し、アプリケーションのフロントコントローラとします。

<?php

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

$app = new Silex\Application();

$app->get('/', function() {
    return 'Hello, World.';
});

$app->run();

ビルトインWebサーバを起動し、localhost:8000にアクセスすればページが表示されます。

% php -S localhost:8000 -t web

最低限必要なのは、composerのautoload.phprequireし、Silex\Applicationのインスタンスを生成したら、run()メソッドを実行することだけです。上の例では$app->get()でルーティングと、それに対応するコントローラも定義しています。

ルーティング

ルーティングは大体、下記のようになります。

$app->get('/', function() {
    return 'Hello, World.';
});

$app->get('/hello', function() {
    return 'Hello, again.';
});

$app->get('/hello2/{name}', function(Silex\Application $app, $name) {
    if(!isset($name)) {
        // リクエストを中断し、HTTPエラーを返す
        $app->abort(404, 'page not found.');
    }
    return 'Hello, '.$name;
});

ルーティングにマッチした際に実行するクロージャにタイプヒント付きでSilexアプリケーションのインスタンスを渡すと、勝手にクロージャ内で$appが使えるようになるようです。次にPOSTルートを見てみます

use Symfony\Component\HttpFoundation\Request;  
use Symfony\Component\HttpFoundation\Response;

...

$app->post('/message', function(Request $request) {
    $message = $request->get('message');
    // create something
    return new Response($message, 201);
});

この例では、Responseのインスタンスを使用して、レスポンスを返しています。この場合はステータスコードと一緒に返すことができます。GETの例のように文字列をreturnする場合はステータスコードは200になります。

HTMLテンプレートを使う

SilexではTwigを利用することができます。まずはTwigをインストールしておきましょう。

% composer require twig/twig

実際にTwigを使うにはProviderという仕組みを利用します。Providerはコードを再利用するための仕組みで、ServiceProviderControllerProviderが提供されています。

Twigを使うにはServiceProviderTwigServiceProviderというのを使います。ServiceProviderを利用するにはアプリケーションにProviderを登録します。

$app = new Silex\Application();

...

$app->register(new Silex\Provider\TwigServiceProvider(), array(
    // options
    'twig.path' => __DIR__.'/../views',
    'twig.options' => array(
        'cache' => __DIR__.'/../cache/twig',
    ),
));

...

$app->get('/', function() {
    return $app->render('index.twig');
});

エラーのハンドリング

404などのエラーを返したい場合には$app->error()を使います。

$app->error(function(\Exception $e, $code) use ($app) {
    return $app['twig']->render('error.twig', array(
        'code' => $code,
        'message' => $e->getMessage()
    ));
});

render()の第2引数はViewに渡すデータになります。

JSONを返す

$app->json()をレスポンスとして返すだけで、Content-Type: application/jsonにしてくれます。

$app->get('/foo', function(Silex\Application $app) {
    return $app->json(array(
        'status' => true,
        'data' => array(
            'foo' => 1,
        ),
        'message' => null,
    ));
});