Laravel - Basics - Session (官方文件原子化翻譯筆記)

# Introduction

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。



# Configuration

Laravel 中, 如果我前面有掛 Load Balancer, 那我 session 要用什麼方式儲存?

centralized store, 像是 database, redis

Laravel 中, 支援哪幾種 session driver?

file, cookie, database, memcached / redis, dynamodb, array

Laravel 中, session driver array 主要用於哪裡?

主要用於 testing, 避免 session 持有化數據


# Driver Prerequisites

# Database

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Schema::create('sessions', function ($table) {
    $table->string('id')->primary();
    $table->foreignId('user_id')->nullable()->index();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->text('payload');
    $table->integer('last_activity')->index();
    });
  • Answer:
    當 session driver 使用 database 時, 需建立一張 table 來存放 session records
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    php artisan session:table

    php artisan migrate
  • Answer:
    當 session driver 使用 database 時, 可使用 CLI 建立存放 session records 的 table

# Interacting With The Session

# Retrieving Data

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Http\Controllers;

    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;

    class UserController extends Controller
    {
    public function show(Request $request, $id)
    {
    $value = $request->session()->get('key');

    //
    }
    }
  • Answer:
    透過 $request 取得 session 'key' 的 value
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = $request->session()->get('key', 'default');

    $value = $request->session()->get('key', function () {
    return 'default';
    });
  • Answer:
    從 $request 取得 session 'key' 的 value, 若 'key' 不可得, 則 return arg2 的 default 值, 或執行 arg2 closure, 取得 closure return 的值

# The Global Session Helper

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::get('/home', function () {
    $value = session('key');

    $value = session('key', 'default');

    session(['key' => 'value']);
    });
  • Answer:
    使用 session global helper
    從 session 中取得 key 為 'key' 的 value
    從 session 中取得 key 為 'key' 的 value, 若 'key' 不可得, return 'default'
    ['key' => 'value'] 存到 session 中

# Retrieving All Session Data

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $data = $request->session()->all();
  • Answer:
    取得 session 中的所有資料

# Determining If An Item Exists In The Session

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    if ($request->session()->has('users')) {
    //
    }
  • Answer:
    判斷 session 中是否有 key 為 'users', 且 value 不為 null
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    if ($request->session()->exists('users')) {
    //
    }
  • Answer:
    判斷 session 是否有 key 為 'users', value 允許為 null

# Storing Data

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->put('key', 'value');

    session(['key' => 'value']);
  • Answer:
    使用 $request 或 session global helper 將 ['key' => 'value'] 存到 session

# Pushing To Array Session Values

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->push('user.teams', 'developers');
  • Answer:
    使用在當要把 item push 到一個 session value 中, 而該 value 是一個 array
    'developers' push 到 session 中的 user.teams, teams 為一個 array

# Retrieving & Deleting An Item

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $value = $request->session()->pull('key', 'default');
  • Answer:
    從 session 中取得並刪除該 record, 若不可能, return arg2 的 'default'

# Flash Data

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->flash('status', 'Task was successful!');
  • Answer:
    使用 flash() 將 ['status' => 'Task was successful!'] 存到 session, 並且可用在下一個 request, 在下一個 request 之後便會自動刪除
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->reflash();

    $request->session()->keep(['username', 'email']);
  • Answer:
    預設使用 flash() 儲存的 session 在下一個 request 之後便會自動刪除
    使用 refresh() 可以延長保存期限, 多一個 request
    使用 keep() 同上, 但只針對特定的 key 延長期限

# Deleting Data

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->forget('name');

    $request->session()->forget(['name', 'status']);

    $request->session()->flush();
  • Answer:
    使用 forget() 從 session 當中移除指定的 key
    使用 flush() 會將 session 中資料完全移除

# Regenerating The Session ID

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $request->session()->regenerate();
  • Answer:
    若使用 Laravel 預設的驗證, 像是 application starter kits 或是 Laravel Fortify, 預設 authenticate user 都會重新產生 session ID
    然而, 也可手動重新產生


# Session Blocking

若要使用 Laravel Session Blocking, 支援哪幾種 session driver?

memcached, dynamodb, redis, database

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::post('/profile', function () {
    //
    })->block($lockSeconds = 10, $waitSeconds = 10)

    Route::post('/order', function () {
    //
    })->block($lockSeconds = 10, $waitSeconds = 10)
  • Answer:
    使用 Session Block
    Laravel 預設允許同時間處理兩個以上帶有相同 session 的 request, 然而, 在少數的情況下可能會有 session 資料丟失的問題, 比方說, 當 request 同時發向同一個 application 兩個不同的 endpoints, 而這兩個不同的 endpoints 會對 session 進行修改
    可使用 block() 避免這個問題, 當使用 block() 時, 在當前 request 完成之前, 該 session 會被 lock 住, 直到該 request 完成後, 才允許相同 session 的下一個 request
    arg1 表示 lock 的時間, 如果 request 完成會自動 release
    arg2 表示新的 request 要嘗試多久來取得新的 session lock, 若超過將會 throw Illuminate\Contracts\Cache\LockTimeoutException
    兩個 args 預設都是 10 秒


# Adding Custom Session Drivers

# Implementing The Driver

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function open($savePath, $sessionName) {}
    public function close() {}
    public function read($sessionId) {}
    public function write($sessionId, $data) {}
    public function destroy($sessionId) {}
    public function gc($lifetime) {}
    }
  • Answer:
    若要自定義 Session Driver, 可在 App\Extensions folder 建立一個 class, 並 implement SessionHandlerInterface, 實作這些 method
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function open($savePath, $sessionName) {}
    }
  • Answer:
    用在 file based session store system, 因為 Laravel 已經有內建的 file session driver, 所以若要自定義 session driver, 這個 method 可以留空
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function close() {}
    }
  • Answer:
    用在 file based session store system, 因為 Laravel 已經有內建的 file session driver, 所以若要自定義 session driver, 這個 method 可以留空
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function read($sessionId) {}
    }
  • Answer:
    當自定義 session driver 時需 implement 的 method
    read() 需 return session data 的 string version
    不需要做任何 serialization, 因為 Laravel 預設做完了
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function write($sessionId, $data) {}
    }
  • Answer:
    當自定義 session driver 時需 implement 的 method
    write() 需將與 $sessionId 相關的 $data string 寫到自定義的 storage 中
    不需要做任何 serialization, 因為 Laravel 預設做完了
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function destroy($sessionId) {}
    }
  • Answer:
    當自定義 session driver 時需 implement 的 method
    destroy() 需將與 $sessionId 有關的 data 從 storage 中移除
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Extensions;

    class MongoSessionHandler implements \SessionHandlerInterface
    {
    public function gc($lifetime) {}
    }
  • Answer:
    當自定義 session driver 時需 implement 的 method
    gc() 需將比 $lifetime 還舊的檔案從 storage 中清掉, 格式為 UNIX timestamp
    如果是使用 self-expiring 系統, 像是 Memcached 或 Redis, 此 method 可留空

# Registering The Driver

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    <?php

    namespace App\Providers;

    use App\Extensions\MongoSessionHandler;
    use Illuminate\Support\Facades\Session;
    use Illuminate\Support\ServiceProvider;

    class SessionServiceProvider extends ServiceProvider
    {
    public function register()
    {
    //
    }

    public function boot()
    {
    Session::extend('mongo', function ($app) {
    // Return an implementation of SessionHandlerInterface...
    return new MongoSessionHandler;
    });
    }
    }
  • Answer:
    當完成自定義的 session driver implementation class 之後, 可在 SessionServiceProvider 的 boot method 中, 使用 Session::extend() 來註冊新的 session driver, mongo 為 session driver 的名稱, closure 會 return implementation class
    註冊完成後, 就可以在 config/session.php 使用 mongo session driver
Recursion - 建立一個 N-level category tree Recursion (遞迴) - 不同類型的遞迴

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×