2024 年 PHP Conference Japan

session_create_id

(PHP 7 >= 7.1.0, PHP 8)

session_create_id建立新的工作階段 ID

說明

session_create_id(字串 $prefix = ""): 字串|false

session_create_id() 用於為目前的階段作業建立新的階段作業 ID。它會返回無衝突的階段作業 ID。

如果階段作業未啟用,則會省略衝突檢查。

階段作業 ID 是根據 php.ini 設定建立的。

重要的是,GC 工作指令碼要使用與您的網路伺服器相同的使用者 ID。否則,您可能會遇到權限問題,尤其是在使用檔案儲存處理器時。

參數

prefix (前綴)

如果指定了 prefix,新的階段作業 ID 會以 prefix 作為前綴。並非所有字元都允許在階段作業 ID 中使用。允許的字元範圍為 [a-zA-Z0-9,-]。最大長度為 256 個字元。

傳回值

session_create_id() 會返回目前階段作業新的無衝突階段作業 ID。如果在未啟用階段作業的情況下使用它,它會省略衝突檢查。失敗時,會返回 false (假)。

範例

範例 #1 使用 session_regenerate_id()session_create_id() 範例

<?php
// 我的 session 啟動函式,支援時間戳記管理
function my_session_start() {
session_start();
// 不允許使用太舊的 session ID
if (!empty($_SESSION['deleted_time']) && $_SESSION['deleted_time'] < time() - 180) {
session_destroy();
session_start();
}
}

// 我的 session ID 重生函式
function my_session_regenerate_id() {
// session 啟用時呼叫 session_create_id() 以
// 確保不會發生碰撞。
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
// 警告:切勿使用機密字串作為前綴!
$newid = session_create_id('myprefix-');
// 設定刪除時間戳記。基於某些原因,session 資料不能立即刪除。
$_SESSION['deleted_time'] = time();
// 結束 session
session_commit();
// 確保接受使用者自訂的 session ID
// 注意:您必須啟用 use_strict_mode 才能正常運作。
ini_set('session.use_strict_mode', 0);
// 設定新的自訂 session ID
session_id($newid);
// 使用自訂 session ID 啟動
session_start();
}

// 確保 use_strict_mode 已啟用。
// 基於安全考量,use_strict_mode 為必要設定。
ini_set('session.use_strict_mode', 1);
my_session_start();

// Session ID 必須在以下情況下重新產生:
// - 使用者登入時
// - 使用者登出時
// - 經過一定時間後
my_session_regenerate_id();

// 撰寫您的程式碼
?>

另請參閱

新增註記

使用者貢獻的註記 1 則註記

rowan dot collins at gmail dot com
7 年前
這個函式很難在使用者端程式碼中精確複製,因為如果已經啟動了工作階段,它會嘗試使用新的「validate_sid」工作階段處理程式回呼來偵測衝突,而這在較早的 PHP 版本中並不存在。

如果您正在使用的處理程式實作了「create_sid」回呼,則可能會在那裡偵測到衝突。當您使用 session_regenerate_id() 時會呼叫此函式,因此您可以使用它來建立新的工作階段,記下其 ID,然後再切換回舊的工作階段 ID。如果沒有啟動任何工作階段,或者目前的處理程式沒有實作「create_sid」和「validate_sid」,則此函式和 session_regenerate_id() 都無法保證不會發生衝突。

如果您有 random_bytes 的合適定義(有一個程式庫可以為 PHP 5.3 以後的版本提供這個功能),您可以使用以下程式碼來產生與 PHP 7.1 相同格式的工作階段 ID。$bits_per_character 應為 4、5 或 6,對應於 session.hash_bits_per_character / session.sid_bits_per_character ini 設定的值。然後您需要手動偵測衝突,例如,透過開啟工作階段並確認 $_SESSION 為空。

<?php
函式 session_create_random_id($desired_output_length, $bits_per_character)
{
$bytes_needed = ceil($desired_output_length * $bits_per_character / 8);
$random_input_bytes = random_bytes($bytes_needed);

// 以下程式碼翻譯自 PHP 原始碼 (ext/session/session.c) 中的 bin_to_readable 函式
static $hexconvtab = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-';

$out = '';

$p = 0;
$q = strlen($random_input_bytes);
$w = 0;
$have = 0;

$mask = (1 << $bits_per_character) - 1;

$chars_remaining = $desired_output_length;
while (
$chars_remaining--) {
if (
$have < $bits_per_character) {
if (
$p < $q) {
$byte = ord( $random_input_bytes[$p++] );
$w |= ($byte << $have);
$have += 8;
} else {
// 理論上不應該發生。輸入必須夠大。
break;
}
}

// 消耗 $bits_per_character 個位元
$out .= $hexconvtab[$w & $mask];
$w >>= $bits_per_character;
$have -= $bits_per_character;
}

return
$out;
}
?>
To Top