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資料,所以不要把$request->session()返回的物件保存在全域陣列或者類成員中導致session無法保存。

獲取所有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 時不建議直接儲存類的實例物件,尤其是來源不可控的類實例,反序列化時可能造成潛在風險。