Laravel Backend Control Website - 5

Laravel 驗證、訊息、中介層 - Validation 、Message、Middleware

第四篇 建立了會員系統,但其中有些東西並沒有交代的很清楚。

比如 資料驗證新增、修改、刪除後的訊息以及 權限的利用,這篇將盡可能的解釋。


第四篇 可以看到儲存或刪除資料後都會有 :

1
return back()->with('success','會員新增成功 !');

這行的意思是退回上一個位置並顯示成功的訊息框,訊息內容為會員新增成功。

相關文件

信息
那這時會有個問題,阿怎麼沒跑出來 ? 這個簡單,因為還沒建立訊息框。

首先要建立 views/_partials/message.blade.php :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@if ($message = Session::get('success'))
<div class="alert alert-success alert-block text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
        <strong>{% raw %}{{ $message }}{% endraw %}</strong>
</div>
@endif


@if ($message = Session::get('error'))
<div class="alert alert-danger alert-block text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
        <strong>{% raw %}{{ $message }}{% endraw %}</strong>
</div>
@endif


@if ($message = Session::get('warning'))
<div class="alert alert-warning alert-block text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
 <strong>{% raw %}{{ $message }}{% endraw %}</strong>
</div>
@endif


@if ($message = Session::get('info'))
<div class="alert alert-info alert-block text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
 <strong>{% raw %}{{ $message }}{% endraw %}</strong>
</div>
@endif

@if ($message = Session::get('nodata'))
<div class="alert alert-info alert-block text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
 <strong>{% raw %}{{ $message }}{% endraw %}</strong>
</div>
@endif

@if ($errors->any())
<div class="alert alert-danger text-center">
 <button type="button" class="close" data-dismiss="alert">×</button> 
 {% raw %}{{ trans('Please check the form below for errors') }}{% endraw %}
</div>
@endif

接著到 _layouts/manage/app.blade.php 中加入 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
   ...略...
</head>
<body>
    <div id="app">
        @include('_partials.manage.nav')
        <main class="py-4">
            @include('_partials.message') <!-- 這行 -->
            @yield('content')
        </main>
    </div>
</body>
</html>

搞定 ! 回到會員管理新增一筆資料看看 !

沒意外新增成功上方會出現成功的訊息。

https://i.imgur.com/aMP6lSD.png
message

想一想,會出現會員新增成功,就代表你通過了驗證。

以下是新增會員的驗證 :

1
2
3
4
5
6
$data = $request->validate([
    'name' => ['required', 'string', 'max:255'],
    'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
    'password' => ['required', 'string', 'min:1', 'confirmed'],
    'permission' => ['required', 'string', 'max:5', 'min:0'],
]);
信息
$request 的解釋請看這邊

簡單來說就是利用 request 來取得輸入資料,並且使用 validate 建立驗證。

可以作為條件的有這些

上面的信箱驗證就是使用了 必填欄位字串格式為信箱最大值255唯一:資料表為users

前面是驗證的設定,接下來看到頁面 create.blade.php 的信箱輸入 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<div class="form-group row">
    <label for="content" class="col-md-4 col-form-label text-md-right">{% raw %}{{ trans('E-Mail Address') }}{% endraw %}</label>
    <div class="col-md-6">
        <input type="text" class="form-control @error('email') is-invalid @enderror" id="email" name="email" value="{% raw %}{{ old('email') }}{% endraw %}" placeholder="{% raw %}{{ trans('E-Mail Address') }}{% endraw %}">
        @error('email')
            <span class="invalid-feedback" role="alert">
                <strong>{% raw %}{{ $message }}{% endraw %}</strong>
            </span>
        @enderror
    </div>
</div>

可以看到 input 中的 @error('email') is-invalid @enderror@error 可以判斷剛剛所設定的驗證是否存在,只要驗證有錯就會在 $message 顯示錯誤訊息。

搭配 Bootstrapis-valid 以及 valid-feedback 來優化顯示錯誤訊息。

https://i.imgur.com/zMvJEaS.png
validation
Tip
表單驗證其實可以自訂,不一定要使用 use Illuminate\Http\Request;Request,以後再說😆

既然 第四篇 建立了會員帳號的權限,以下就提出一些使用的例子。

比如我們規定 權限大於0 才能進入後台,這裡就要提到一下 中介層 / middleware

信息
中介層提供一個方便的機制來過濾進入應用程式的 HTTP 請求。

之前我們透過 php artisan:make auth 的指令創建了名為 auth 的中介層 ./app/Http/Middleware/Authenticate.php

中介層名字定義在 ./app/Http/Kernel.php :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    ......

    protected $routeMiddleware = [
        'admin' => \App\Http\Middleware\Admin::class,      <!-- 等等要加入的 -->
        'auth' => \App\Http\Middleware\Authenticate::class,
        ......
    ];
    
    ......

可以看到 adminauth 兩個中介層,admin 是等等要創立的,意義是管理員才能進入後台 ; 而 auth 代表是否有登入。

輸入以下指令生成中介層 Admin.php :

1
php artisan make:middleware Admin

將內容改為 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php

namespace App\Http\Middleware;

use Closure;

class Admin
{
    public function handle($request, Closure $next)
    {
        if (auth()->user()->permission != 0) {
            return $next($request);
        }
        return redirect('home');
    }
}

上面的意思就是如果登入權限不等於0才能存取路由,否則就要導回前台頁面。(auth用法)

接下來將中介層加入 Kernel.php 後就到 web.php 中加入中介層。

1
2
3
4
5
Route::get('/manage', function () {return view('manage.index');})->middleware('auth','admin')->name('manage');
Route::prefix('manage')->middleware('auth','admin')->group(function(){
    Route::resource('member', 'MemberController');
});
//必須登入且權限大於零才能進入後台

可以創立一個權限為 一般使用者 的試看看登入後進入後台

再來的例子是帳號權限是否可以對會員帳號進行新增修改,請在 _partial/manage/nav.blade.php 做以下修改 :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
    <div class="container-fluid">
        <a class="navbar-brand" href="{% raw %}{{ url('/manage') }}{% endraw %}">
            {% raw %}{{ config('app.name', 'Laravel') }}{% endraw %}
        </a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{% raw %}{{ __('Toggle navigation') }}{% endraw %}">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <!-- Left Side Of Navbar -->
            <ul class="navbar-nav mr-auto">
                @if (Auth::check() && Auth::user()->permission > '4')
                <li class="nav-item">
                    <a class="nav-link" href="{% raw %}{{ route('member.index') }}{% endraw %}">{% raw %}{{ __('Member').__('Manage') }}{% endraw %}</a>
                </li>
                @endif
            </ul>

            <!-- Right Side Of Navbar -->
            <ul class="navbar-nav ml-auto">
                <li class="nav-item">
                    <a class="nav-link" href="{% raw %}{{ route('home') }}{% endraw %}">{% raw %}{{ __('Fontstage') }}{% endraw %}</a>
                </li>
                <li class="nav-item dropdown">
                    <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                        {% raw %}{{ Auth::user()->name }}{% endraw %} <span class="caret"></span>
                    </a>

                    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                        <a class="dropdown-item" href="{% raw %}{{ route('logout') }}{% endraw %}"
                           onclick="event.preventDefault();
                                         document.getElementById('logout-form').submit();">
                            {% raw %}{{ trans('Logout') }}{% endraw %}
                        </a>

                        <form id="logout-form" action="{% raw %}{{ route('logout') }}{% endraw %}" method="POST" style="display: none;">
                            @csrf
                        </form>
                    </div>
                </li>
            </ul>
        </div>
    </div>
</nav>

可以看到其中的 :

1
2
3
4
5
@if (Auth::check() && Auth::user()->permission > '4')
<li class="nav-item">
    <a class="nav-link" href="{% raw %}{{ route('member.index') }}{% endraw %}">{% raw %}{{ __('Member').__('Manage') }}{% endraw %}</a>
</li>
@endif

上述表示權限不大於4無法進入會員管理的頁面。

另外你可以在Controller中加入 :

1
2
3
4
5
6
7
public function create()
{
    if (Auth::check() && Auth::user()->permission < '5') {
        return back()->with('warning', '權限不足以訪問該頁面 !');
    }
    return view('manage.member.create');
}

上述表示權限小於5無法進入會員新增的頁面。

諸如此類的例子,就交給你自由發揮了😉


1
php artisan make:controller MemberController --resource

--resource 代表建立了一個包含CRUD的控制器。

函數用途
index()顯示資料(一般是列表)
create()建立新資料(通常是表單界面)
store(Request $request)儲存資料
show($id)顯示某筆資料
edit($id)編輯某筆資料(通常是表單界面)
update(Request $request, $id)更新某筆資料
destroy($id)刪除某筆資料

如果要建立一個空的控制器 :

1
php artisan make:controller MemberController

如果要同時建立 modelmigrationcontroller --resource :

1
php artisan make:model Member -mcr
參數用途
-m為model建立一個數據庫
-c為model建立一個控制器
-r為控制器加入 –resource 參數

可以用下列指令看到所有可用選項 :

1
php artisan make:model --help

Hope it will help !