laravel使ってみた

普段はpythonを使っているが、この度laravelを使った開発にも手を出してみた。
初めてなので慣れるため実装した機能などは極力自作、コマンドの使用は最小限に。

##使用言語
php
laravel
html
scss
ちょっとjs

##完成物
![17E6C5B3-E75A-417B-9DDC-9E22F92B798E_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074981/4af22cdb-cc81-9bb8-0896-a679c0614606.jpeg)
トップページからは、新規会員登録、ログイン、お問い合わせ画面に遷移ができる。

①新規会員登録した場合、ログイン画面に遷移。ログインした場合は掲示板画面に遷移
②ログインした場合、ログイン後の画面に遷移。(以下の画面)
![FF5605EF-DD68-42B1-ACCC-DBF510CC8082_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074981/c091f0c4-77a7-521f-1caf-fe70aa04c695.jpeg)
③この画面では、ログアウト、新規投稿、マイページ、掲示板に遷移することができる

次の章からは、重要になってくるコードのみ紹介する(コード量が膨大なため)

##controller
まずはcontrollerから
##マイページのコントローラー
```php5:MypageController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Models\Post;

class MypageController extends Controller
{

    //全てのページでログインしていない状態だとloginページに強制的にリダイレクトされる
    public function getUser(){
        $me = Auth::user()->id;
        //find()の戻り値はModelオブジェクトだからforeachとかが使えない。一方で、get()の返り値はCollectionクラスでforeach()で回せば各々の値を取得できる
        $my_posts = Post::where('user_id',$me)->get();
        return view('/user/mypage', ['my_posts' => $my_posts]);
    }
}
```

ここで重要なのはAuthの使い方。他のサイトに載っているので参考にした。しかし、ある程度使い方を理解していなければ応用が効かないと思う。

##contactController
```php5:contactController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Mail\ContactSendmail;

class ContactController extends Controller
{
    //フォーム入力画面のviewを表示
    public function contact_top(){
        return view('contact/contact_top');
    }

    public function confirm(Request $request){

        //バリデーションを実行(結果に問題があれば処理を中断してエラーを返す)
        $request->validate([
            'email'=>'required|email',
            'title'=>'required',
            'quest_body'=>'required'
        ]);

        //フォームから受け取った全ての入力された値(このフォームではinputの値)を取得
        $inputs = $request->all();

        //入力内容確認ページのviewに変数を渡して表示
        //compact('inputs')は['inputs' => $inputs]としても同じ
        return view('contact/confirm', compact('inputs'));
    }

    public function send(Request $request){
            //フォームから受け取ったactionの値(キー)を取得(nameとvalueは連想配列の形になっていることが重要)
            $action = $request->input('action');
            //フォームから受け取ったactionを除いたinputの値を取得
            $inputs = $request->except('action');
            //actionの値で分岐

            //redirect()の横のroute
            if($action !== 'submit'){
                return redirect()->route('contact.top')->withInput($inputs);
            }else{
                //入力されたメールアドレスにメールを返信
                \Mail::to($inputs['email'])->send(new ContactSendmail($inputs));
                //再送信を防ぐためにトークンを再発行
                $request->session()->regenerateToken();
                //送信完了ページのviewを表示
                return view('contact/thanks');
            }

    }
}
```
これは、メールの自動送信機能を作るためのコード。ここで重要なのは.envファイルに記入事項を確実に追加すること。(ContactSendmailのオブジェクト参照)
これが設定できていなければ、メール機能は使えないので注意が必要。

##LoginController
```php5:LoginController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    //ログイン画面を表示
    public function login(){
        return view('/user/login');
    }

    //ログインするための実際の処理
    public function login_user(Request $request){
        $remember = true;

        $request -> validate([  //バリデーション
            'login_email' => 'required | email',
            'login_password' => 'required|min:8'
        ]);

        //既にユーザー認証している(既にログインしている)場合の処理。flashをviewで表示するように設定している
        if(Auth::check()){
            return redirect('/') -> with('logged_message', '既にログインしています');
        }

        //inputで入力された値がレコードに存在しているかどうかを確かめるためのコード。存在していたらtrueを返す。存在しなかったらflaseを返して、flashを表示
        if(Auth::attempt(['email' => $request->input('login_email'), 'password' => $request->input('login_password')], $remember)){
            //dbに登録されていてログインできる場合、マイページに飛ばす
            return redirect()->route('index.top');
        }
        else{
            return back()->with('not_exists_db_message', 'ログインできませんでした');
        }
    }
}

```
これはログイン機能を作るためのコントローラーである。重要なのはAuthの使い方と、useで使うパッケージを指定するのを忘れないこと。
ログイン機能は正直authを使いこなせれば、簡単に作ることができる。

##ルート(web.php)
```php5:web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Controller;
use App\Http\Controllers\RegisterController;
use App\Http\Controllers\LoginController;
use App\Http\Controllers\LogoutController;
use App\Http\Controllers\CustomerController;
use Illuminate\Support\Facades\Auth;



/*
|--------------------------------------------------------------------------
| 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!
|
*/

/* Route::get('/', function () {
    return view('welcome');
}); */

//トップページ
Route::get('/', 'App\Http\Controllers\CustomerController@index') -> name('index.top');

//フォーム入力ページ(フォームトップページ)
Route::get('/contact', 'App\Http\Controllers\ContactController@contact_top') -> name('contact.top');
//確認ページ
Route::post('/contact/confirm', 'App\Http\Controllers\ContactController@confirm') -> name('contact.confirm');
//送信完了ページ
Route::post('/contact/thanks', 'App\Http\Controllers\ContactController@send') -> name('contact.send');

//新規ユーザー登録
Route::get('/register', 'App\Http\Controllers\RegisterController@register') -> name('register.user');
Route::post('/create', 'App\Http\Controllers\RegisterController@create') -> name('register.create');

//ログイン
Route::get('/login', 'App\Http\Controllers\LoginController@login') -> name('login.user');
Route::post('/login_user', 'App\Http\Controllers\LoginController@login_user') -> name('login.create');



Route::group(['middleware' => 'auth'], function(){
    //マイページの表示とログアウト
    Route::get('/mypage/{id}', 'App\Http\Controllers\MypageController@getUser') -> name('mypage');
    Route::get('/logout', 'App\Http\Controllers\LogoutController@getLogout') -> name('user.logout');

    //新規投稿機能
    Route::get('/post/new', 'App\Http\Controllers\PostController@postNew') -> name('post.new');
    Route::post('/post/create', 'App\Http\Controllers\PostController@postCreate') -> name('post.create');
});

Route::get('/post/all', 'App\Http\Controllers\PostController@postAll') -> name('post.all');
```
特に特筆すべき点はないが、一つ挙げるならば、nameを使った方がいいということ。nameを使うことで後々ルート指定するときにかなり楽になる。また、どのrouteを指しているのか非常にわかりやすくなる。

##学習すべき点
今回のようなアプリを作成するときに、学習するべきところは以下だと思う。
これはあくまでも僕の意見です。

①authなどのライブラリ
②middlewareを使ってマイページを作る方法。routeの設定の仕方
③mysqlでdbを用いる際のデプロイを視野に入れた開発

##まとめ
つらつら書いてきたが、正直middleware、authとかのライブラリの使い方を勉強すればsns・掲示板は十分作れる。
あとはクライアントサイドで動作する言語を使う場合はちょっと複雑になるけど特に難しい部分はない。
一緒にがんばりましょう。

【ついき】
教えていただいたことも参考にすると、コントローラーに処理を全部書かないで、イベントに分けて作成した方がログイン機能とかは簡単になるかもしれん。