チュウトリアル
TOP| |1||2||3||4||5||6||インスト1||インスト2||インスト3||Linux


Lumenでスレッド掲示板をつくろう!

■実行サンプル
http://bb.s3.to/topics

■スレッド掲示板定義
・ルートの設計
GET    /topics		トピック一覧
GET    /topics/{id}	トピック詳細・コメント表示
GET    /post		トピック投稿フォーム
POST   /topics		トピック投稿
POST   /topics/{id}	コメント投稿

・データベースの設計
トピックテーブル topics
・タイトル
・コメント数

コメントテーブル comments
・トピックID
・名前
・本文


■Lumenインストール
#composer create-project laravel/lumen --prefer-dist

#cd lumen

■初期設定
・「bootstrap/app.php」を編集
#vi bootstrap/app.php
環境設定を.envで行う
// Dotenv::load(__DIR__.'/../');
↓
Dotenv::load(__DIR__.'/../');

FacadeとEloquentを使用する
// $app->withFacades();
// $app->withEloquent();
↓
$app->withFacades();
$app->withEloquent();

環境設定ファイル.envを編集
データベースはSQLiteを使用する
・「.env.example」を「.env」にリネームして編集
#mv .env.example .env
#vi .env
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
↓
DB_CONNECTION=sqlite
# DB_HOST=localhost
# DB_DATABASE=homestead
# DB_USERNAME=homestead
# DB_PASSWORD=secret

・SQLitneデータベース用ファイル作成
#touch storage/database.sqlite


■テーブルの作成
・「topics」テーブル マイグレーション作成
# php artisan make:migration create_topic_table --create=topics

・「topics」テーブル マイグレーション編集
#vi  database/migrations/2015_06_xx_xxxx_create_topic_table.php
		Schema::create('topics', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('title');
			$table->integer('comment_num')->unsigned();
			$table->timestamps();


・「comment」テーブル マイグレーション作成
# php artisan make:migration create_comment_table --create=comments

・「comment」テーブル マイグレーション編集
#vi  database/migrations/2015_06_xx_xxxx_create_comments_table.php
		Schema::create('comments', function(Blueprint $table)
		{
			$table->increments('id');
			$table->integer('topic_id')->unsigned();
			$table->string('name');
			$table->text('body');
			$table->timestamps();

・マイグレート実行
#php artisan migrate

■モデルの作成
・Topicモデルをappディレクトリに作成
#vi app/Topic.php
<?php namespace App;

use Illuminate\Database\Eloquent\Model;


class Topic extends Model
{
    // 代入可能な項目
     protected $fillable = ['title', 'comment_num'];

     public function comments()
     {
          // トピックはたくさんのコメントを持つ
          return $this->hasMany('App\Comment');
     }
}

・Commentモデルをappディレクトリに作成
#vi app/Comment.php
<?php namespace App;

use Illuminate\Database\Eloquent\Model;


class Comment extends Model
{
     protected $fillable = ['topic_id', 'name', 'body'];
}

■初期データの挿入
「database/seeds/DatabaseSeeder.php」を編集する
#vi database/seeds/DatabaseSeeder.php

・先頭に使用するモデルクラスをuse

use App\Topic;
use App\Comment;

・呼び出すクラスを記述
// $this->call('UserTableSeeder');
↓
$this->call('TopicTableSeeder');

・初期データを挿入するクラスを記述。
class TopicTableSeeder extends Seeder
{

	public function run()
	{
		DB::table('topics')->delete();
		DB::table('comments')->delete();

               for ($i = 1; $i <= 5; $i++) {
                   $topic  = new Topic;
                   $topic->title = 'title' . $i;
                   $topic->comment_num = 0;
                   $topic->save();

                   // コメント
                   $num = mt_rand(1, 5);
                   for ($j = 0; $j < $num; $j++) {
                       $com = new Comment;
                       $com->name = 'noname';
                       $com->body = str_random(32);
                       $com->topic_id = $topic->id;

                       $com->save();
                       $topic->increment('comment_num');
                   }
              }
	}
}

・実行
#php artisan db:seed

■ビューファイルの作成
#vi  resources/views/index.blade.php
<p>
    <h3>新着トピック</h3>
    <hr><button class="btn btn-warning"
    onclick="location.href='{{ url('post') }}'">トピックを投稿する</button><br><br>
    @foreach($topics as $topic)
    <div>
        {{ $topic->comment_num }}コメント   {{ $topic->created_at->format('Y/m/d H:i') }}
        <h4><a href="{{ url('/topics', $topic->id) }}">{{ $topic->title }}</a></h4>

        <hr>
    </div>
    @endforeach
</p>

■トピック一覧の表示確認
・ルートファイル修正
#vi app/Http/routes.php
use App\Topic;

$app->get('/topics', function() use ($app) {
    $topics  = Topic::all();

    return view('topics', compact('topics'));
});

■ビューファイルの作成
・ベースファイルを作成し共通化
#vi resources/views/base.blade.php
<body>

<div class="container">
<div class="row">
    <div class="col-xs-offset-2 col-xs-8">
    @yield('content')
    </div>
</div>
</div>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>

ソース→base.blade.php

#vi resources/views/index.blade.php
@extends('base')

@section('content')
<p>
    <h3>新着トピック</h3>
〜〜〜〜
〜〜〜〜
@stop

ソース→index.blade.php

■Formクラスを使えるようにする
・インストール
#composer require laravelcollective/html

・以下をbootstrap/app.phpに追加
#vi bootstrap/app.php
$app->register('Collective\Html\HtmlServiceProvider');
class_alias('Collective\Html\HtmlFacade', 'Html');
class_alias('Collective\Html\FormFacade', 'Form');

・HtmlBuilder.phpとFormBuilder.phpをlumen用に修正
#vi ./vendor/laravelcollective/html/src/HtmlBuilder.php
use Illuminate\Routing\UrlGenerator;
↓
use Laravel\Lumen\Routing\UrlGenerator;

#vi ./vendor/laravelcollective/html/src/FormBuilder.php
use Illuminate\Routing\UrlGenerator;
↓
use Laravel\Lumen\Routing\UrlGenerator;

・Mencachedエラー
・.envを修正
CACHE_DRIVER=mencached
SESSION_DRIVER=memcached
↓
CACHE_DRIVER=file
SESSION_DRIVER=cookie

・トピック投稿用ビュー
#vi resources/views/post.blade.php
@extends('base')

@section('content')
        <h2>トピックを投稿する</h2>
        <hr>
        {!! Form::open(['url' => 'topics']) !!}

        <div class="form-group">
            {!! Form::label('title', 'タイトル') !!}
            {!! Form::text('title', null, ['placeholder'=>'必須入力',
            'style'=>'width:50%','class'=>'form-control']) !!}
        </div>

          <div class="form-group">
            {!! Form::label('name', '名前(空白でも可)') !!}
            {!! Form::text('name', null, ['placeholder'=>'空白でも可',
            'style'=>'width:50%','class'=>'form-control']) !!}
        </div>

        <div class="form-group">
            {!! Form::label('body', '本文') !!}
            {!! Form::textarea('body', null, ['placeholder'=>'必須入力',
            'style'=>'width:80%','class'=>'form-control']) !!}
        </div>
<br><br>
        <div class="form-group">
            {!! Form::submit(' トピックを投稿する ', ['class'=>'btn btn-primary']) !!}
        </div>

    {!! Form::close() !!}
@stop

ソース→post.blade.php

・トピック詳細・コメント表示ビュー
#vi resources/views/show.blade.php

ソース→show.blade.php


■コントーラーの作成
#vi app/Http/TopicController.php
<?php namespace App\Http\Controllers;

use App\Topic;
use App\Http\Controllers\Controller;

class TopicController extends Controller {

    public function index()
    {
        // created_at大きい順(最新順)に表示
        $topics  = Topic::latest()->get();

        return view('index', compact('topics'));
    }

    public function create()
    {
        return view('post');
    }

    public function show($id)
    {
        // $idのトピックを取得。失敗したらエラー
        $topic = Topic::findOrfail($id);

        return view('show', compact('topic'));
    }

■ルートの修正
#vi app/Http/routes.php
$c = 'App\Http\Controllers\TopicController';

$app->get('topics', $c.'@index');
$app->get('topics/{id}', $c.'@show');
$app->get('post', $c.'@create');
$app->post('topics', $c.'@store');
$app->post('topics/{id}', $c.'@store_comment');
$app->delete('topics/{$id}', $c.'@destroy');

■投稿処理の作成
#vi app/Http/TopicController.php
・トピック投稿処理
public function store(Request $request)
    {
        // フォームからの入力をすべて受け取る
        $data = $request->all();
        // バリデーションルール
        $rules = [
        'title' =>  'required|min:6',
        'body'  =>  'required',
        ];
        // バリデーターを通す
        $v = \Validator::make($data, $rules);

        // 失敗した場合 エラーを出力して戻る(まだエラー表示がうまくいかない
        if ($v->fails()) {
            return redirect('post')->withErrors($v->errors());
        }
        // トピックテーブルへデータを保存。トピック数は1
        $topic = new Topic;
        $topic->title = $data['title'];
        $topic->comment_num = 1;
        $topic->save();
        // コメントテーブルへデータを保存。トピックIDは$topic->idで取得できる
        $comment = new Comment;
        $comment->topic_id = $topic->id;
        $comment->name = $data['name'];
        $comment->body = $data['body'];
        $comment->save();

        return redirect('topics');
    }

・コメント投稿処理
    public function store_comment(Request $request,$id)
    {
        $topic = Topic::findOrfail($id);
        $data = $request->all();
        $rules = [
        'body'  =>  'required',
        ];

        $v = \Validator::make($data, $rules);

        if ($v->fails()) {
            return redirect('topics/'.$id)->withErrors($v->errors());
        }
        // コメント数を増やす
        $topic->increment('comment_num');

        $comment = new Comment;
        $comment->topic_id = $id;
        // 名無しさん
        $comment->name = (trim($data['name'])) ? $data['name'] : '匿名';
        $comment->body = $data['body'];
        $comment->save();

        return redirect('topics/'.$id);
    }

リファクタリングが必要かな
LastModified July 06 2015 15:41:36
HOME||チュウトリアル||使用上の注意||スクリプト||無料鯖情報||BBS||リンク
Copyright(C) 1999-2017 ToR all rights reserved.