webman session 管理
範例
<?php
namespace app\controller;
use support\Request;
class UserController
{
public function hello(Request $request)
{
$name = $request->get('name');
$session = $request->session();
$session->set('name', $name);
return response('hello ' . $session->get('name'));
}
}
透過 $request->session(); 取得 Workerman\Protocols\Http\Session 實例,並透過實例的方法來新增、修改、刪除 session 資料。
注意
session 物件銷毀時會自動儲存 session 資料
將 session 物件儲存到全域變數會阻止 session 銷毀,導致無法自動儲存 session 資料,此時需手動呼叫$session->save()儲存
取得所有 session 資料
$session = $request->session();
$all = $session->all();
回傳值為陣列。若沒有任何 session 資料,則回傳空陣列。
取得 session 中某個值
$session = $request->session();
$name = $session->get('name');
若資料不存在則回傳 null。
你也可以在 get 方法的第二個參數傳入預設值,若 session 陣列中沒找到對應值則回傳該預設值。例如:
$session = $request->session();
$name = $session->get('name', 'tom');
儲存 session
儲存單一筆資料時使用 set 方法。
$session = $request->session();
$session->set('name', 'tom');
set 沒有回傳值,session 物件銷毀時 session 會自動儲存。
當儲存多個值時使用 put 方法。
$session = $request->session();
$session->put(['name' => 'tom', 'age' => 12]);
同樣地,put 也沒有回傳值。
刪除 session 資料
刪除單一項或多項 session 資料時使用 forget 方法。
$session = $request->session();
// 刪除一項
$session->forget('name');
// 刪除多項
$session->forget(['name', 'age']);
另外系統提供了 delete 方法,與 forget 方法不同的是,delete 只能刪除一項。
$session = $request->session();
// 等同於 $session->forget('name');
$session->delete('name');
取得並刪除 session 某個值
$session = $request->session();
$name = $session->pull('name');
效果與以下程式碼相同
$session = $request->session();
$value = $session->get('name');
$session->delete('name');
若對應的 session 不存在,則回傳 null。
刪除所有 session 資料
$request->session()->flush();
沒有回傳值,session 物件銷毀時 session 會自動從儲存中刪除。
判斷對應 session 資料是否存在
$session = $request->session();
$has = $session->has('name');
以上當對應的 session 不存在或對應的 session 值為 null 時回傳 false,否則回傳 true。
$session = $request->session();
$has = $session->exists('name');
以上程式碼也可用來判斷 session 資料是否存在,差別在於當對應的 session 項值為 null 時,也會回傳 true。
輔助函數 session()
webman 提供了輔助函數 session() 來完成相同功能。
// 取得 session 實例
$session = session();
// 等同於
$session = $request->session();
// 取得某個值
$value = session('key', 'default');
// 等同於
$value = session()->get('key', 'default');
// 等同於
$value = $request->session()->get('key', 'default');
// 給 session 賦值
session(['key1'=>'value1', 'key2' => 'value2']);
// 相當於
session()->put(['key1'=>'value1', 'key2' => 'value2']);
// 相當於
$request->session()->put(['key1'=>'value1', 'key2' => 'value2']);
設定檔
session 設定檔位於 config/session.php,內容類似如下:
use Webman\Session\FileSessionHandler;
use Webman\Session\RedisSessionHandler;
use Webman\Session\RedisClusterSessionHandler;
return [
// FileSessionHandler::class 或 RedisSessionHandler::class 或 RedisClusterSessionHandler::class
'handler' => FileSessionHandler::class,
// handler 為 FileSessionHandler::class 時值為 file,
// handler 為 RedisSessionHandler::class 時值為 redis
// handler 為 RedisClusterSessionHandler::class 時值為 redis_cluster(即 Redis 叢集)
'type' => 'file',
// 不同的 handler 使用不同的設定
'config' => [
// type 為 file 時的設定
'file' => [
'save_path' => runtime_path() . '/sessions',
],
// type 為 redis 時的設定
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'auth' => '',
'timeout' => 2,
'database' => '',
'prefix' => 'redis_session_',
],
'redis_cluster' => [
'host' => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7001'],
'timeout' => 2,
'auth' => '',
'prefix' => 'redis_session_',
]
],
'session_name' => 'PHPSID', // 儲存 session_id 的 cookie 名稱
'auto_update_timestamp' => false, // 是否自動重新整理 session,預設關閉
'lifetime' => 7*24*60*60, // session 過期時間
'cookie_lifetime' => 365*24*60*60, // 儲存 session_id 的 cookie 過期時間
'cookie_path' => '/', // 儲存 session_id 的 cookie 路徑
'domain' => '', // 儲存 session_id 的 cookie 網域
'http_only' => true, // 是否開啟 httpOnly,預設開啟
'secure' => false, // 僅在 https 下開啟 session,預設關閉
'same_site' => '', // 用於防止 CSRF 攻擊與使用者追蹤,可選值 strict/lax/none
'gc_probability' => [1, 1000], // 回收 session 的機率
];
安全性
使用 session 時不建議直接儲存類的實例物件,尤其來自不可控來源的類實例,反序列化時可能造成潛在安全風險。