Difference between revisions of "Basic Laravel Training (for CV)"

From Ta Wiki
Jump to navigation Jump to search
 
(30 intermediate revisions by the same user not shown)
Line 62: Line 62:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
# ลองสร้าง method index
 
# ลองสร้าง method index
 
+
#: <syntaxhighlight lang="php" line>
 +
    public function index(){
 +
        $menu = array("Home", "My course", "Setting");
 +
        return $menu;
 +
    }
 +
</syntaxhighlight>
 +
# เพิ่ม Route ใน <code>routes/web.php</code>
 +
#: <syntaxhighlight lang="php" line>
 +
Route::get('home','page_controller@index');
 +
</syntaxhighlight>
 +
# ลองทดสอบเรียก url
 +
#: <pre>http://localhost:8000/home</pre>
 +
# ปกติแล้วสิ่งที่ controller คืนมักจะไม่ใช่ array หรือ object ธรรมดา ยกเว้นกรณีที่กำลังเขียน api .. หากเป็นกรณี webpage มักจะคืนเป็น view
 +
# ลองสร้าง view (การสร้าง view จะไม่สามารถเรียกผ่าน artisan ได้ จะต้องสร้างด้วยตัวเอง ใน <code>resources/views</code> โดยให้สร้าง view ชื่อว่า <code>home.blade.php</code>
 +
# ใน controller method index จะเปลี่ยนแปลงการ return ให้ return view แทน
 +
#: <syntaxhighlight lang="php" line>
 +
    public function index(){
 +
        $menu = array("Home", "My course", "Setting");
 +
        return view("home")->with('menu',$menu);
 +
    }
 +
</syntaxhighlight>
 +
# ใน <code>home.blade.php</code> ให้ลองเขียน html เพื่อแสดง menu เป็น unordered list
 +
#: <syntaxhighlight lang="html" line>
 +
<!DOCTYPE html>
 +
<html lang="en">
 +
<head>
 +
    <meta charset="UTF-8">
 +
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 +
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 +
    <title>Document</title>
 +
</head>
 +
<body>
 +
    <ul>
 +
        @foreach($menu as $eachmenu)
 +
            <li>{{$eachmenu}}</li>
 +
        @endforeach
 +
    </ul>
 +
</body>
 +
</html>
 +
</syntaxhighlight>
 
==== View (Blade Template) ====
 
==== View (Blade Template) ====
 +
* <code><meta name="csrf-token" content="{{ csrf_token() }}"></code>
 +
* <code>{{ config('app.name', 'Laravel') }}</code>
 +
* @include('inc.messages')
 +
* @yield('content')
 +
* @extends('layouts.app')
 +
* @section('content')<br>@endsection
 +
* @if
 +
* @for
 +
* @foreach
 +
* @csrf
 +
* {{}}
 +
* {!!  !!}
  
 
=== Database ===
 
=== Database ===
 +
==== Preparation ====
 +
* สร้าง database (สมมติว่าชื่อ laravel_training)
 +
* แก้ไข <code>.env</code>
 +
*: <syntaxhighlight>
 +
DB_CONNECTION=mysql
 +
DB_HOST=127.0.0.1
 +
DB_PORT=3306
 +
DB_DATABASE=laravel_training
 +
DB_USERNAME=USERNAME
 +
DB_PASSWORD=PASSWORD
 +
</syntaxhighlight>
 +
* แก้ไข file <code>app/Providers/AppServiceProvider.php</code> ข้างบนสุดเพิ่ม
 +
*: <pre>use Illuminate\Support\Facades\Schema;</pre>
 +
* แก้ไข file <code>app/Providers/AppServiceProvider.php</code> function boot เพิ่ม
 +
*: <pre>Schema::defaultStringLength(191);</pre>
 +
* ลอง migrate default script
 +
*: <pre>php artisan migrate</pre>
 +
 
==== Model & DB ====
 
==== Model & DB ====
 
* php artisan make:model MODEL_NAME --migration
 
* php artisan make:model MODEL_NAME --migration
 
* php artisan make:migration MIGRATION_NAME
 
* php artisan make:migration MIGRATION_NAME
 +
* Sample
 +
*: <!--syntaxhighlight lang="php">
 +
<?php
 +
    public function up()
 +
    {
 +
        Schema::enableForeignKeyConstraints();
 +
        Schema::create('cvdrive_comments', function (Blueprint $table) {
 +
            $table->increments('id');
 +
            $table->text('comment')->nullable($value = true);
 +
            $table->integer('cvdrive_item_id')->unsigned();
 +
            $table->integer('user_id')->unsigned();
 +
            $table->integer('cvdrive_comment_id')->unsigned()->nullable($value = true);
 +
            $table->timestamps();
 +
 +
            $table->foreign('cvdrive_item_id')->references('id')->on('cvdrive_items')->onDelete('cascade');
 +
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
 +
            $table->foreign('cvdrive_comment_id')->references('id')->on('cvdrive_comments')->onDelete('cascade');
 +
        });
 +
    }
 +
 +
    public function down()
 +
    {
 +
        Schema::dropIfExists('cvdrive_comments');
 +
    }
 +
}
 +
 +
</syntaxhighlight-->
  
 
==== Eloquent ====
 
==== Eloquent ====
 +
* php artisan tinker
 +
* new item
 +
*: <syntaxhighlight lang="php">
 +
$course = new course();
 +
$course->number = "2110221";
 +
$course->title = "Computer Engineering Essentials";
 +
$course->year = 2018;
 +
$course->semester = 2;
 +
$course->save();
 +
</syntaxhighlight>
 +
* duplicate item : $newcourse2 = $newcourse->replicate();
 +
* fetch item
 +
*: <syntaxhighlight lang="php">
 +
$allcourses = course::all();
 +
$findcourse = course::find(1);
 +
$findcourse = course::where(number,"2110221")->get();
 +
 +
// ->where("title","like","%".$keyword."%")
 +
// ->orderBy('created_at','desc')
 +
// ->paginate(10);
 +
// In view show page numbers: {{$items->links()}}
 +
</syntaxhighlight>
 +
* edit item
 +
*: <syntaxhighlight lang="php">
 +
$course = course::find(1);
 +
$course->title = "NEW NAME";
 +
$course->save();
 +
</syntaxhighlight>
 +
* delete item
 +
*: <syntaxhighlight lang="php">
 +
$course = course::find(1);
 +
$course->delete();
 +
</syntaxhighlight>
  
 
==== Handle CRUD ====
 
==== Handle CRUD ====
Line 76: Line 205:
 
* method: get, post, patch, delete
 
* method: get, post, patch, delete
 
* Route::resource('ROUTE', 'CONTROLLER');
 
* Route::resource('ROUTE', 'CONTROLLER');
 +
* php artisan route:list
 +
* Handle request
 +
*: <syntaxhighlight lang="php">
 +
$name = $request->input('name', 'Default');
 +
$name = $request->name;
 +
</syntaxhighlight>
 +
* Validation --> [https://laravel.com/docs/5.8/validation See Doc]
 +
*: <syntaxhighlight lang="php">
 +
$request->validate([
 +
    'title' => 'required|max:255',
 +
    'body' => 'required',
 +
]);
 +
 +
// Frontend display error
 +
@if ($errors->any())
 +
    <div class="alert alert-danger">
 +
        <ul>
 +
            @foreach ($errors->all() as $error)
 +
                <li>{{ $error }}</li>
 +
            @endforeach
 +
        </ul>
 +
    </div>
 +
@endif
 +
</syntaxhighlight>
 +
 +
==== Relationship ====
 +
===== one to one =====
 +
* Defining relationship
 +
*: return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
 +
* Defining inverse relationship
 +
*: return $this->belongsTo('App\User', 'foreign_key', 'other_key');
 +
 +
===== one to many =====
 +
* Defining relationship
 +
*: return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
 +
* Defining inverse relationship
 +
*: return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
 +
 +
===== many to many =====
 +
* Defining relationship
 +
*: return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
 +
*: return $this->belongsToMany('Model','Intermediate table name','fk of current model','fk of another model')
 +
* Defining inverse relationship
 +
*: return $this->belongsToMany('App\User', 'role_user', 'role_id', 'user_id');
 +
*: return $this->belongsToMany('Model','Intermediate table name','fk of current model','fk of another model')
  
 
=== Authentication ===
 
=== Authentication ===
 +
==== Preparation ====
 +
* php artisan make:auth
 +
 
==== User System ====
 
==== User System ====
 +
* $user = Auth::user();
 +
* $id = Auth::id();
 +
* Protect route
 +
*: <syntaxhighlight lang="php">
 +
// Protect in route
 +
Route::get('index','homecontroller@index')->middleware('auth');
 +
 +
// Protect in constructor
 +
public __construct{
 +
    $this->middleware('auth', ['except' => ['getActivate', 'anotherMethod']]);
 +
}
 +
</syntaxhighlight>
 +
* Check if the user is loggedin
 +
*: <syntaxhighlight lang="php">
 +
if (Auth::check()) {
 +
    // The user is logged in...
 +
}
 +
</syntaxhighlight>
  
 
==== Access Control ====
 
==== Access Control ====
 +
* Using Policy
 +
* php artisan make:policy POLICY_NAME
 +
* php artisan make:policy POLICY_NAME --model=MODEL // Create with basic CRUD
 +
* Register Policy in <code>App/Providers/Authserviceprovider.php</code>
 +
*: <syntaxhighlight lang="php">
 +
    protected $policies = [
 +
        Post::class => PostPolicy::class,
 +
    ];
 +
</syntaxhighlight>
 +
* Writing Policy
 +
*: <syntaxhighlight lang="php">
 +
public function update(User $user, Post $post){
 +
    return $user->id === $post->user_id;
 +
}
 +
 +
// Check Policy
 +
if ($user->can('update', $post)) {
 +
    //
 +
}
 +
</syntaxhighlight>
 +
* Writing Policy without model
 +
*: <syntaxhighlight lang="php">
 +
public function create(User $user){
 +
    //
 +
}
 +
 +
// Check Policy
 +
if ($user->can('create', Post::class)) { // ต้องบอก class เพื่อจะได้รู้ว่าจะไปเรียกจาก policy ของ class ไหน
 +
    //
 +
}
 +
</syntaxhighlight>
 +
* Writing Policy in View
 +
*: <syntaxhighlight lang="php">
 +
@can('update', $post)
 +
    <!-- The Current User Can Update The Post -->
 +
@elsecan('create', App\Post::class)
 +
    <!-- The Current User Can Create New Post -->
 +
@endcan
 +
 +
 +
@if (Auth::user()->can('update', $post))
 +
    <!-- The Current User Can Update The Post -->
 +
@endif
 +
 +
 +
@unless (Auth::user()->can('update', $post))
 +
    <!-- The Current User Can't Update The Post -->
 +
@endunless
 +
</syntaxhighlight>
 +
 +
== Testing ==
 +
* Make test <syntaxhighlight>
 +
// Create a test in the tests/Feature directory...
 +
php artisan make:test UserTest
 +
 +
// Create a test in the tests/Unit directory...
 +
php artisan make:test UserTest --unit
 +
</syntaxhighlight>
 +
* Run test : In your project root run <pre>vendor/bin/phpunit</pre>
 +
* The CSRF middleware is automatically disabled when running tests
 +
* Use model factory to generate fake object
 +
** Factory is at <code> database/factories/UserFactory.php</code>
 +
** In testing <syntaxhighlight lang="php">
 +
$user = factory(User::class)->create();
 +
$response = $this->actingAs($user)->withSession(['foo' => 'bar'])->get('/');
 +
</syntaxhighlight>
 +
* Browser Test [[https://laravel.com/docs/5.8/dusk https://laravel.com/docs/5.8/dusk]]
 +
* And more ... in Laravel Doc
 +
 +
== More and More ==
 +
=== Middleware ===
 +
* อยู่ระหว่าง routing กับ controller
 +
** มีอยู่แล้วคือ Auth
 +
** อาจมีอื่นๆ เช่น CORS middleware, Log middleware
 +
* การสร้าง Middleware
 +
** <code>php artisan make:middleware CheckAge</code>
 +
** File จะอยู่ที่ <code> app/Http/Middleware</code>
 +
** ตัวอย่างนี้ เป็น middleware ที่เช็ค age
 +
*** ถ้า age <= 200 จะไม่อนุญาตให้ไปต่อ โดยจะ redirect ไปที่ home
 +
*** ถ้า age > 200 จะไปต่อ โดยเรียก $next($request) $next คือ function ที่มันควรจะเข้าจริงๆ
 +
** <syntaxhighlight lang="php">
 +
<?php
 +
 +
namespace App\Http\Middleware;
 +
 +
use Closure;
 +
 +
class CheckAge
 +
{
 +
    /**
 +
    * Handle an incoming request.
 +
    *
 +
    * @param  \Illuminate\Http\Request  $request
 +
    * @param  \Closure  $next
 +
    * @return mixed
 +
    */
 +
    public function handle($request, Closure $next)
 +
    {
 +
        if ($request->age <= 200) {
 +
            return redirect('home');
 +
        }
 +
 +
        return $next($request);
 +
    }
 +
}
 +
</syntaxhighlight>
 +
** Middleware อาจจะทำก่อน หริือ หลัง request ก็ได้
 +
*** ทำก่อน (ตัวอย่างกรณีข้างบน)
 +
*** ทำหลัง <syntaxhighlight lang="php">
 +
    public function handle($request, Closure $next)
 +
    {
 +
        $response = $next($request);
 +
 +
        // Perform action
 +
 +
        return $response;
 +
    }
 +
</syntaxhighlight>
 +
* หลังจากสร้างแล้ว จะต้องเอาไป register ไว้ที่ <code> app/Http/Kernel.php</code>
 +
* การนำไปใช้
 +
** จะเอาไปผูกกับ route <syntaxhighlight lang="php">
 +
Route::get('admin/profile', function () {
 +
    //
 +
})->middleware('auth', 'second_middleware');
 +
</syntaxhighlight>
 +
* Middleware group (Assign ทีเดียวหลายตัวเป็น group)
 +
* Middleware parameters
 +
** ตัวอย่างการเช็ค role <syntaxhighlight lang="php">
 +
<?php
 +
 +
namespace App\Http\Middleware;
 +
 +
use Closure;
 +
 +
class CheckRole
 +
{
 +
    /**
 +
    * Handle the incoming request.
 +
    *
 +
    * @param  \Illuminate\Http\Request  $request
 +
    * @param  \Closure  $next
 +
    * @param  string  $role
 +
    * @return mixed
 +
    */
 +
    public function handle($request, Closure $next, $role)
 +
    {
 +
        if (! $request->user()->hasRole($role)) {
 +
            // Redirect...
 +
        }
 +
 +
        return $next($request);
 +
    }
 +
 +
}
 +
</syntaxhighlight>
 +
** การนำไปใช้ กรณีนี้จะตรวจสอบว่า route นี้จะเข้าได้เฉพาะคนที่มี role เป็น editor เท่านั้น <syntaxhighlight lang="php">
 +
Route::put('post/{id}', function ($id) {
 +
    //
 +
})->middleware('role:editor');
 +
</syntaxhighlight>
 +
 +
=== OAUTH ===
 +
* [[https://laravel.com/docs/5.8/passport Laravel Passport (Library for OAUTH Server)]]
 +
 +
== More References ==
 +
* [[https://github.com/alexeymezenin/laravel-best-practices#follow-laravel-naming-conventions Laravel Best Practices]]

Latest revision as of 00:13, 26 April 2019

Reference

  • Laravel Documentation
https://laravel.com/docs/5.8

Installation

Requirements

  • PHP >= 7.1.3
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension
  • Ctype PHP Extension
  • JSON PHP Extension
  • BCMath PHP Extension

Steps

  1. Install LAMP Stack (ie. XAMPP) อย่าลืมจำ mysql root password!!
  2. Install Composer
    https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
    หมายเหตุ: เวลาเรียกใช้งาน composer อาจจะต้องใช้ ./composer.phar แทนที่ composer ถ้าทำการ Install composer เป็น local
  3. สร้าง Laravel Project โดยใช้ composer
    composer create-project --prefer-dist laravel/laravel PROJECT_NAME 
  4. Run Local Development Server
    php artisan serve # for running on localhost:8000
    or
    php artisan serve --port=8888 # for running on localhost:8888

Basic Tutorial

Important directory / file

  • app Where the models are
    • Http
      • Controllers
      • Middleware
  • config
  • database
  • public Where the public files (ie. css, js)
  • resources
    • views
  • routes
    • api.php
    • web.php
  • vendor Where the additional libraries store
  • .env all environment variables (ie. DB username/password)

Intro

Controller & Route

  1. Let's make a controller: page_controller
    php artisan make:controller CONTROLLER_NAME
    จะมีไฟล์ app/Http/Controllers/page_controller.php ปรากฎ
  2. ในไฟล์จะมี code เหล่านี้
     1 <?php
     2 
     3 namespace App\Http\Controllers;
     4 
     5 use Illuminate\Http\Request;
     6 
     7 class page_controller extends Controller
     8 {
     9     //
    10 }
    
  3. ลองสร้าง method index
    1     public function index(){
    2         $menu = array("Home", "My course", "Setting");
    3         return $menu;
    4     }
    
  4. เพิ่ม Route ใน routes/web.php
    1 Route::get('home','page_controller@index');
    
  5. ลองทดสอบเรียก url
    http://localhost:8000/home
  6. ปกติแล้วสิ่งที่ controller คืนมักจะไม่ใช่ array หรือ object ธรรมดา ยกเว้นกรณีที่กำลังเขียน api .. หากเป็นกรณี webpage มักจะคืนเป็น view
  7. ลองสร้าง view (การสร้าง view จะไม่สามารถเรียกผ่าน artisan ได้ จะต้องสร้างด้วยตัวเอง ใน resources/views โดยให้สร้าง view ชื่อว่า home.blade.php
  8. ใน controller method index จะเปลี่ยนแปลงการ return ให้ return view แทน
    1     public function index(){
    2         $menu = array("Home", "My course", "Setting");
    3         return view("home")->with('menu',$menu);
    4     }
    
  9. ใน home.blade.php ให้ลองเขียน html เพื่อแสดง menu เป็น unordered list
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     7     <title>Document</title>
     8 </head>
     9 <body>
    10     <ul>
    11         @foreach($menu as $eachmenu)
    12             <li>{{$eachmenu}}</li>
    13         @endforeach
    14     </ul>
    15 </body>
    16 </html>
    

View (Blade Template)

Database

Preparation

  • สร้าง database (สมมติว่าชื่อ laravel_training)
  • แก้ไข .env
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_training
    DB_USERNAME=USERNAME
    DB_PASSWORD=PASSWORD
  • แก้ไข file app/Providers/AppServiceProvider.php ข้างบนสุดเพิ่ม
    use Illuminate\Support\Facades\Schema;
  • แก้ไข file app/Providers/AppServiceProvider.php function boot เพิ่ม
    Schema::defaultStringLength(191);
  • ลอง migrate default script
    php artisan migrate

Model & DB

  • php artisan make:model MODEL_NAME --migration
  • php artisan make:migration MIGRATION_NAME
  • Sample

Eloquent

  • php artisan tinker
  • new item
    $course = new course();
    $course->number = "2110221";
    $course->title = "Computer Engineering Essentials";
    $course->year = 2018;
    $course->semester = 2;
    $course->save();
    
  • duplicate item : $newcourse2 = $newcourse->replicate();
  • fetch item
    $allcourses = course::all();
    $findcourse = course::find(1);
    $findcourse = course::where(number,"2110221")->get();
    
    // ->where("title","like","%".$keyword."%")
    // ->orderBy('created_at','desc')
    // ->paginate(10);
    // In view show page numbers: {{$items->links()}}
    
  • edit item
    $course = course::find(1);
    $course->title = "NEW NAME";
    $course->save();
    
  • delete item
    $course = course::find(1);
    $course->delete();
    

Handle CRUD

  • php artisan make:controller CONTROLLER_NAME --resource
  • method: get, post, patch, delete
  • Route::resource('ROUTE', 'CONTROLLER');
  • php artisan route:list
  • Handle request
    $name = $request->input('name', 'Default'); 
    $name = $request->name;
    
  • Validation --> See Doc
    $request->validate([
        'title' => 'required|max:255',
        'body' => 'required',
    ]);
    
    // Frontend display error
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
    

Relationship

one to one
  • Defining relationship
    return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
  • Defining inverse relationship
    return $this->belongsTo('App\User', 'foreign_key', 'other_key');
one to many
  • Defining relationship
    return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
  • Defining inverse relationship
    return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
many to many
  • Defining relationship
    return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
    return $this->belongsToMany('Model','Intermediate table name','fk of current model','fk of another model')
  • Defining inverse relationship
    return $this->belongsToMany('App\User', 'role_user', 'role_id', 'user_id');
    return $this->belongsToMany('Model','Intermediate table name','fk of current model','fk of another model')

Authentication

Preparation

  • php artisan make:auth

User System

  • $user = Auth::user();
  • $id = Auth::id();
  • Protect route
    // Protect in route
    Route::get('index','homecontroller@index')->middleware('auth');
    
    // Protect in constructor
    public __construct{
        $this->middleware('auth', ['except' => ['getActivate', 'anotherMethod']]);
    }
    
  • Check if the user is loggedin
    if (Auth::check()) {
        // The user is logged in...
    }
    

Access Control

  • Using Policy
  • php artisan make:policy POLICY_NAME
  • php artisan make:policy POLICY_NAME --model=MODEL // Create with basic CRUD
  • Register Policy in App/Providers/Authserviceprovider.php
        protected $policies = [
            Post::class => PostPolicy::class,
        ];
    
  • Writing Policy
    public function update(User $user, Post $post){
        return $user->id === $post->user_id;
    }
    
    // Check Policy
    if ($user->can('update', $post)) {
        //
    }
    
  • Writing Policy without model
    public function create(User $user){
        //
    }
    
    // Check Policy
    if ($user->can('create', Post::class)) { // ต้องบอก class เพื่อจะได้รู้ว่าจะไปเรียกจาก policy ของ class ไหน
        // 
    }
    
  • Writing Policy in View
    @can('update', $post)
        <!-- The Current User Can Update The Post -->
    @elsecan('create', App\Post::class)
        <!-- The Current User Can Create New Post -->
    @endcan
    
    
    @if (Auth::user()->can('update', $post))
        <!-- The Current User Can Update The Post -->
    @endif
    
    
    @unless (Auth::user()->can('update', $post))
        <!-- The Current User Can't Update The Post -->
    @endunless
    

Testing

  • Make test
    // Create a test in the tests/Feature directory...
    php artisan make:test UserTest
    
    // Create a test in the tests/Unit directory...
    php artisan make:test UserTest --unit
  • Run test : In your project root run
    vendor/bin/phpunit
  • The CSRF middleware is automatically disabled when running tests
  • Use model factory to generate fake object
    • Factory is at database/factories/UserFactory.php
    • In testing
      $user = factory(User::class)->create();
      $response = $this->actingAs($user)->withSession(['foo' => 'bar'])->get('/');
      
  • Browser Test [https://laravel.com/docs/5.8/dusk]
  • And more ... in Laravel Doc

More and More

Middleware

  • อยู่ระหว่าง routing กับ controller
    • มีอยู่แล้วคือ Auth
    • อาจมีอื่นๆ เช่น CORS middleware, Log middleware
  • การสร้าง Middleware
    • php artisan make:middleware CheckAge
    • File จะอยู่ที่ app/Http/Middleware
    • ตัวอย่างนี้ เป็น middleware ที่เช็ค age
      • ถ้า age <= 200 จะไม่อนุญาตให้ไปต่อ โดยจะ redirect ไปที่ home
      • ถ้า age > 200 จะไปต่อ โดยเรียก $next($request) $next คือ function ที่มันควรจะเข้าจริงๆ
    • <?php
      
      namespace App\Http\Middleware;
      
      use Closure;
      
      class CheckAge
      {
          /**
           * Handle an incoming request.
           *
           * @param  \Illuminate\Http\Request  $request
           * @param  \Closure  $next
           * @return mixed
           */
          public function handle($request, Closure $next)
          {
              if ($request->age <= 200) {
                  return redirect('home');
              }
      
              return $next($request);
          }
      }
      
    • Middleware อาจจะทำก่อน หริือ หลัง request ก็ได้
      • ทำก่อน (ตัวอย่างกรณีข้างบน)
      • ทำหลัง
            public function handle($request, Closure $next)
            {
                $response = $next($request);
        
                // Perform action
        
                return $response;
            }
        
  • หลังจากสร้างแล้ว จะต้องเอาไป register ไว้ที่ app/Http/Kernel.php
  • การนำไปใช้
    • จะเอาไปผูกกับ route
      Route::get('admin/profile', function () {
          //
      })->middleware('auth', 'second_middleware');
      
  • Middleware group (Assign ทีเดียวหลายตัวเป็น group)
  • Middleware parameters
    • ตัวอย่างการเช็ค role
      <?php
      
      namespace App\Http\Middleware;
      
      use Closure;
      
      class CheckRole
      {
          /**
           * Handle the incoming request.
           *
           * @param  \Illuminate\Http\Request  $request
           * @param  \Closure  $next
           * @param  string  $role
           * @return mixed
           */
          public function handle($request, Closure $next, $role)
          {
              if (! $request->user()->hasRole($role)) {
                  // Redirect...
              }
      
              return $next($request);
          }
      
      }
      
    • การนำไปใช้ กรณีนี้จะตรวจสอบว่า route นี้จะเข้าได้เฉพาะคนที่มี role เป็น editor เท่านั้น
      Route::put('post/{id}', function ($id) {
          //
      })->middleware('role:editor');
      

OAUTH

More References