【Laravel7】簡単なTwitter風のSNSアプリの作成手順【初心者向け】

CODE

この記事は、PHPのフレームワーク「Laravel」でTwitterのようなアプリを作成するための解説記事です。

私(わや@wayasblog)自身、Laravelを最近勉強し始めたので、かなり丁寧に解説した初心者向けの記事となっています。

コードだけ見たい!という方は、こちら(GitHub)からどうぞ。

今回は以下の記事を参考に、機能を少し追加してみました。

Laravelで超簡単SNSを作ろう!(実践編) - Qiita
Laravelを使って、簡単なSNSを作ろうのコーナーです! 完成形はこんな感じです〜〜 自信がない方、作り方だけ知れればいいよーっていうかたはこちらをご覧ください! 日本語でまなぼ!twitter風SNSアプリ開発!(MVC...

スポンサーリンク

Laravelで作るTwitter風のSNSアプリのイメージ

スクリーンショットで紹介していきます。
今回は、Bootstrapで簡単にスタイルを作成しました。

タイムラインページ(未ログイン)

未ログイン状態だと、タイムラインは見れますがツイートはできません。

タイムラインページ(ログイン後)

ログイン後は、ツイートできるようになります。

ツイート時のバリデーション

何も入力せずにツイートボタンを押した時のバリデーション。

140文字以上入力した時のバリデーション。

ツイート時の動画

新しいツイートが1番上に挿入されます。

初期設定

お決まりの初期設定をしていきます。

Laravelのインストール

composer create-project --prefer-dist laravel/laravel laravel_sns

「laravel_sns」というフォルダの中に、Laravelがインストールされました。

phpMyAdimnでDB作成

今回は「laravel_sns」というDBを作成しました。

.envファイルの設定

DBの設定のため、.envファイルを編集します。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_sns
DB_USERNAME=root
DB_PASSWORD=root

configファイルの設定

config/app.phpで日本語と時間の設定をします。

'timezone' => 'Asia/Tokyo',
'locale' => 'ja',

以上で、初期設定は終わりです。

ログイン機能の実装

Laravelでは、簡単にログイン機能を実装することができます。

composer require laravel/ui
php artisan ui vue --auth

以上の2つのコマンドを実行するだけ。

なぜかログイン画面などにBootstrapのCSSが読み込まれないので、resources/views/layouts/app.blade.phpで読み込ませます。

CSSやJSは、こちらからどうそ。

Introduction
Get started with Bootstrap, the world’s most popular framework for building responsive, mobile-first sites, with BootstrapCDN and a template starter page.

これでログイン機能の実装ができました。

コントローラーの作成

php artisan make:controller TimelineController

app/Http/Controllers/TimelineController.phpが作成されました。

ここに、以下のfunctionを作っていきます。

  • showTimelinePage
  • postTweet

※postTweetは、DB挿入のためのものでページは作成しないので、viewは渡しません。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TimelineController extends Controller
{
    public function showTimelinePage()
    {
        return view('timeline');
    }

    public function postTweet()
    {

    }
}

ルーティングの設定

routes/web.phpを編集します。

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::get('/timeline', 'TimelineController@showTimelinePage')->name('timeline');
Route::post('/timeline', 'TimelineController@postTweet')->name('timeline');

ビューの作成

resources/viewstimeline.balde.phpを作成します。

フォームは「Laravel Collective」の「Forms & HTML」を使うので、インストールします。
※参考:Laravel Collective

composer require laravelcollective/html

timeline.balde.phpの中身は以下の通りです。

@extends('layouts.app')

@section('content')
    <div class="container mt-3">
        {!! Form::open(['route' => 'timeline', 'method' => 'POST']) !!}
            {{ csrf_field() }}
            <div class="row mb-4">
                {{ Form::text('tweet', null, ['class' => 'form-control col-9 mr-auto']) }}
                {{ Form::submit('ツイート', ['class' => 'btn btn-primary col-2']) }}
            </div>
        {!! Form::close() !!}
    </div>
@endsection

モデルとマイグレーションの作成

モデルはDBとの連携を行う機能で、マイグレーションはDBを管理する機能です。

php artisan make:model Tweet -m

コマンドで-mを付けると、database/migrationsにマイグレーションファイルも一緒に作られるので、中身を書いていきましょう。

<?php

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

class CreateTweetsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tweets', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->text('name');
            $table->text('tweet');
            $table->timestamps();
        });
    }

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

同時にapp/Tweet.phpが作成されるので、中身を書いていきます。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tweet extends Model
{
    protected $fillable = [
        'user_id',
        'name',
        'tweet',
    ];
}

ここまで完了したら、以下のコマンドでDBにテーブルが作成されます。

php artisan migrate

バリデーションの設定

app/Http/Controllers/TweetController.phppostTweetの中に書いていきます。

public function postTweet(Request $request)
    {
        $request->validate([
            'tweet' => 'required|max:140',
        ]);
    }

timeline.blade.phpにエラーを表示させます。

@extends('layouts.app')

@section('content')
    <div class="container mt-3">
        {!! Form::open(['route' => 'timeline', 'method' => 'POST']) !!}
            {{ csrf_field() }}
            <div class="row mb-4">
                {{ Form::text('tweet', null, ['class' => 'form-control col-9 mr-auto']) }}
                {{ Form::submit('ツイート', ['class' => 'btn btn-primary col-2']) }}
            </div>
            {{-- エラー表示 ここから --}}
            @if ($errors->has('tweet'))
                <p class="alert alert-danger">{{ $errors->first('tweet') }}</p>
            @endif
            {{-- エラー表示 ここまで --}}
        {!! Form::close() !!}
    </div>
@endsection

このままだと英語で表示されるので、日本語化していきます。

resources/langのenフォルダと同階層にjaフォルダを作成し、validation.phpをコピペ。

修正した箇所は以下の通りです。

'max' => [
        'string' => ':attributeは:max文字以内で入力してください。',
    ],
'required' => ':attributeは必ず入力してください。',
'attributes' => [
        'tweet' => 'ツイート',
    ],

ツイートした内容を、タイムラインで表示する

app/Http/Controllers/TweetController.phpに追記します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use \App\Tweet;

class TimelineController extends Controller
{
    public function showTimelinePage()
    {
        $tweets = Tweet::latest()->get();

        return view('timeline', [
            'tweets' => $tweets,
        ]);
    }

    public function postTweet(Request $request)
    {
        $request->validate([
            'tweet' => 'required|max:140',
        ]);

        Tweet::create([
            'user_id' => Auth::user()->id,
            'name'    => Auth::user()->name,
            'tweet'   => $request->tweet,
        ]);

        return back();
    }
}

実際にツイートをビューで表示していきます。

resources/views/timeline.blade.phpはこのようになりました。

@extends('layouts.app')

@section('content')
    <div class="container mt-3">
        {!! Form::open(['route' => 'timeline', 'method' => 'POST']) !!}
            {{ csrf_field() }}
            <div class="row mb-4">
                {{ Form::text('tweet', null, ['class' => 'form-control col-9 mr-auto']) }}
                {{ Form::submit('ツイート', ['class' => 'btn btn-primary col-2']) }}
            </div>
            @if ($errors->has('tweet'))
                <p class="alert alert-danger">{{ $errors->first('tweet') }}</p>
            @endif
        {!! Form::close() !!}

        @foreach ($tweets as $tweet)
            <div class="mb-1">
                <strong>{{ $tweet->name }}</strong> {{ $tweet->created_at }}
            </div>
            <div class="pl-3">
                {{ $tweet->tweet }}
            </div>
            <hr>
        @endforeach
    </div>
@endsection

ログイン状態でのみツイートできるようにする

ログイン状態のみツイートできるようにして、ログインしていない場合はタイムラインを見ることだけができるように条件分岐します。

resources/views/timeline.blade.phpを変更。

@extends('layouts.app')

@section('content')
    <div class="container mt-3">
        {!! Form::open(['route' => 'timeline', 'method' => 'POST']) !!}
            {{ csrf_field() }}
            <div class="row mb-4">
                {{-- 変更ここから --}}
                @guest
                    <div class="mx-auto">
                        <a class="btn btn-primary" href="{{ route('login') }}">ログインしてツイートする</a>
                        <a class="btn btn-primary" href="{{ route('register') }}">新規登録してツイートする</a>
                    </div>
                @else
                    {{ Form::text('tweet', null, ['class' => 'form-control col-9 mr-auto']) }}
                    {{ Form::submit('ツイート', ['class' => 'btn btn-primary col-2']) }}
                @endguest
                {{-- 変更ここまで --}}
            </div>
            @if ($errors->has('tweet'))
                <p class="alert alert-danger">{{ $errors->first('tweet') }}</p>
            @endif
        {!! Form::close() !!}

        @foreach ($tweets as $tweet)
            <div class="mb-1">
                <strong>{{ $tweet->name }}</strong> {{ $tweet->created_at }}
            </div>
            <div class="pl-3">
                {{ $tweet->tweet }}
            </div>
            <hr>
        @endforeach
    </div>
@endsection

ログイン、ログアウト後のリダイレクト先をタイムラインに変更

ログイン機能を実装した段階で、

  • ログイン後 → /home
  • 新規登録後 → /home
  • ログアウト後 → /

とデフォルトで決まってしまっているので、これを直接タイムラインに行くように設定します。

app/Http/Controllers/Auth/LoginController.phpを変更

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = 'timeline';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    protected function loggedOut($request)
    {
        return redirect(route('timeline'));
    }
}

app/Http/Controllers/Auth/RegisterController.phpも上記と同じ箇所を変更します。

/**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = 'timeline';

resources/views/home.blade.phpは消しておきました。

以上で、簡単なものではありますが、Twitter風のSNSアプリの完成です。
お疲れさまでした\(^o^)/

【まとめ】簡単なTwitter風のSNSアプリの作成手順

Laravelを使うと、結構簡単にTwitter風のアプリができて感動しています。

これからもどんどんアウトプットしていこうと思います。

コード全体を見たい!という方は、こちら(GitHub)からどうぞ。

以上です。
最後まで見てくださり、ありがとうございました。

最後に宣伝

ココナラで、コーディングの相談を受け付けています。

  • CSSが上手く作れない
  • JavaScriptが思ったように動かない
  • ブログのデザインを修正したい
  • 勉強中でわからないところがあるから教えてほしい

このようなお悩みを解決していますので、「こんなの解決できる?」ということがあったら、ぜひ質問だけでも以下のリンクよりどうぞ。

HTML / CSS / JSのお悩みを解決します コーディングでお困りの方はお気軽にお問い合わせください! | Webサイト制作に関する相談 | ココナラ
HTML / CSS / JavaScript(jQuery)のお悩み相談、ご質問を受け付けます。「CSSが上手く作れない」「JavaScriptが思ったように...

コメント

タイトルとURLをコピーしました