Ray Lee | 李宗叡
Learn or Die
Published in
15 min readJan 3, 2021

--

Photo by Christopher Laberinto on Unsplash

# 版本

Laravel 8.x

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# 目錄

Laravel — 官方文件原子化翻譯 — 目錄

# 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();

# 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

--

--

Ray Lee | 李宗叡
Learn or Die

It's Ray. I do both backend and frontend, but more focus on backend. I like coding, and would like to see the whole picture of a product.