atijust's blog

技術的なこととか。

Laravel4でブログチュートリアルっぽいのをやってみた - その1

手を動かして覚えたいので、ちょうどいい課題としてCakePHPのブログチャートリアルっぽいのをLaravel4でやってみた。

動作要件

Lravel4の動作要件は以下の2つ。

手元ではPHP5.5.5と組み込みサーバで動作を確認している。

インストール

Composerを使ってインストール。

$ composer create-project laravel/laravel --prefer-dist demo-blog
Installing laravel/laravel (v4.0.9)
  - Installing laravel/laravel (v4.0.9)
    Loading from cache

Created project in demo-blog
Loading composer repositories with package information
Installing dependencies (including require-dev)
### 中略 ###
Writing lock file
Generating autoload files
Generating optimized class loader
Application key [nROO9YVu3ZmwxXMlRDI32sz1l0mxo71n] set successfully.

zipをダウンロードしてきてインストールすることもできるみたいだけど、どのみちComposerが必要なのであまり意味はない。

動作確認

インストールが成功したかどうか確認。 プロジェクトのトップディレクトリで./artisan serveを実行する。

$ cd demo-blog
$ ./artisan serve
Laravel development server started on http://localhost:8000

PHPの組み込みサーバが立ち上がるので、ブラウザでhttp://localhost:8000にアクセスする。Laravelのロゴが表示されれば成功。

artisanはLaravelのコマンドラインツールで、開発に便利な各種機能を提供している。ここでは単にPHPの組み込みサーバを立ち上げるのに使ったが、DBのマイグレーションやシーディングなど、なにかとお世話になるコマンド。

Laravelの設定

タイムゾーン

app/config/app.php

    'timezone' => 'Asia/Tokyo',

デフォだとUTCなので変更しておく。

データベース

app/config/database.php

    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'demo_blog',
        'username'  => 'root',
        'password'  => '',
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    ),

ブログ用にdemo_blogというデータベースを使うことにする。 MySQL以外にもPostgres、SQLiteSQL Serverがサポートされているので、どれを使うかは好みで。設定方法は設定ファイルのコメントに書いてある。

データベースの作成

Laravelのマイグレーション機能を使ってテーブルを作成する。 demo_blogデータベースはコマンドラインなりツールであらかじめ作成しておく。

まずはartisanでマイグレーションのひな形を作成する。

$ ./artisan migrate:make create_posts_table --table=posts --create
Created Migration: 2013_10_30_002418_create_posts_table
Generating optimized class loader

スキーマビルダーを使ってテーブルを組み立てる。

app/database/migrations/2013_10_30_002418_create_posts_table.php

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('title', 50);
            $table->text('body');
            $table->dateTime('updated_at');
            $table->dateTime('created_at');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('posts');
    }

}

updated_atcreated_atというカラムがあれば、ORMがモデルの更新、作成時に自動的に時刻を設定してくれる。

マイグレーションを実行。

$ ./artisan migrate
Migration table created successfully.
Migrated: 2013_10_30_002418_create_posts_table

これでdemo_blogデータベースにpostsテーブルが作成された。

Postモデルの作成

LaravelにはEloquentというORMが含まれている。オーソドックスなActiveRecordタイプで使いやすい。

モデルのクラスファイルはオートローダでロードできるならどこに置いてもいいけど、取り敢えず最初から用意されているapp/modelsディレクトリを使うことにする。

app/models/Post.php

<?php

class Post extends Eloquent
{
}

モデルは規約によってクラス名の複数形のテーブルと対応する。もちろん規約外のテーブル名を使うことも出来る。

ダミーデータの用意

データベースにブログ記事のダミーデータを用意する。 コマンドライン、あるいは適当なツールでデータベースに直接データを入れてもいいのだが、Laravelに用意されているSeed機能を使ってみることにする。

app/database/seeds/DatabaseSeeder.phpにデフォルトのSeederクラスが用意されているのでこれを使う。

app/database/seeds/DatabaseSeeder.php

<?php

class DatabaseSeeder extends Seeder {

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Eloquent::unguard();
        DB::table('posts')->truncate();
        Post::create(['title' => 'はじめてのLaravel', 'body' => 'Hello, Laravel!']);
    }

}

Postモデルを使ってレコードを作成。

artisanで実行する。

$ ./artisan db:seed
Database seeded!

Postコントローラの作成

コントローラはapp/controllersに設置する。例によってオートローダでロードできるならここ以外のディレクトリに設置することもできる。

app/controllers/PostController.php

<?php

class PostController extends BaseController
{
    public function index()
    {
        $posts = Post::all();
        return View::make('post.index', ['posts' => $posts]);
    }

    public function show($id)
    {
        $post = Post::findOrFail($id);
        return View::make('post.show', ['post' => $post]);
    }
}

記事一覧を表示するindexアクションと、記事を表示するshowアクションを用意した。先ほど作成したPostモデルからブログ記事を取得し、View::make()でビューをレンダリングしている。

次にアクションとURLを結びつけるためにルーティングを設定する。ルーティングの設定はapp/routes.phpに記述する。もちろんこれ以外の場所(ServiceProviderとか)で設定することもできる。

app/routes.php

<?php

Route::get('/', 'PostController@index');
Route::get('/{id}', 'PostController@show');

Postビューの作成

LaravelにはBladeというシンプルなテンプレートエンジンが含まれている。今回はこれを使うことにする。 もちろんだけど、Blade以外にPHP、Twig、Smartyなどなんでも好きなものを使うことができる。Packagistで検索するとLaravel用のパッケージが見つかる。

まずはPostController@indexに対応する記事一覧のビューファイル。

app/views/post/index.blade.php

<!doctype html>
<html lang="ja">
<head>
  <title>Demo Blog</title>
  <meta charset="UTF-8">
</head>
<body>
<h1>Demo Blog</h1>
@foreach ($posts as $post)
  <a href="{{ action('PostController@show', $post->id) }}">{{{ $post->title }}}</a> {{ $post->created_at }}<br />
@endforeach
</body>
</html>

制御構文は@からはじまる。 {{}}で囲まれた部分はechoされる。{{{}}}で囲まれている場合はエスケープされてからechoされる。 URLの生成には各種ヘルパーメソッドが用意されている。ここではコントローラのアクションに引数を指定してURLを生成している。

次はPostController@indexに対応する記事を表示するビュー。

app/views/post/show.blade.php

<!doctype html>
<html lang="ja">
<head>
  <title>Demo Blog</title>
  <meta charset="UTF-8">
</head>
<body>
<h1>{{{ $post->title }}}</h1>
<p>{{{ $post->body }}}</p>
</body>
</html>

以上でブログの記事一覧と記事表示の機能は完成。 コマンドラインからartisanでPHPの組み込みサーバを立ち上げ、http://localhost:8000にアクセスすれば記事一覧が表示されるはず。

記事の投稿、編集、削除とユニットテスト

ちょっと疲れたので、記事の投稿、編集、削除については後日あらためて作成することにする。いまどきテストを書かないわけにもいかないので、テストもしっかり用意したいと思う。

最後になったが、Laravelの学習には日本語ドキュメントを使わせていただいた。翻訳して公開してくださった川瀬氏に感謝。