(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)
session_regenerate_id — 使用新生成的會話 ID 更新現(xiàn)有會話 ID
$delete_old_session
= false
): boolsession_regenerate_id() 在不修改當前會話中數(shù)據(jù)的前提下使用新的 ID 替換原有會話 ID。
如果啟用了 session.use_trans_sid 選項, 那么必須在調(diào)用 session_regenerate_id() 函數(shù)之后開始進行輸出工作, 否則會導致使用原有的會話 ID。
當前的 session_regenerate_id 并沒有很好的處理在諸如移動數(shù)據(jù)網(wǎng)絡和 WiFi 網(wǎng)絡不穩(wěn)定的場景。 因此,調(diào)用 session_regenerate_id 函數(shù) 可能會導致會話丟失。
你不應該直接銷毀舊的會話所關(guān)聯(lián)的數(shù)據(jù), 而是應該使用時間戳機制來控制對于已經(jīng)失效的會話 ID 的訪問。 否則,可能會在并發(fā)訪問的場景下導致會話數(shù)據(jù)不一致、 會話丟失等情況,甚至可能引發(fā)客戶端(瀏覽器)創(chuàng)建很多無用的會話 ID。 但是,另外一方面來講,立即刪除會話中的數(shù)據(jù) 可以防止會話劫持攻擊。
delete_old_session
是否刪除原 ID 所關(guān)聯(lián)的會話存儲文件。 如果你需要避免會話并發(fā)訪問沖突,那么不應該立即刪除會話中的數(shù)據(jù)。 如果你需要防止會話劫持攻擊,那么可以立即刪除會話數(shù)據(jù)。
成功時返回 true
, 或者在失敗時返回 false
。
示例 #1 A session_regenerate_id() 示例
<?php
// 注意:下列不是完整的代碼,只是一個示例
session_start();
// 檢查會話被銷毀的時間戳
if (isset($_SESSION['destroyed'])
&& $_SESSION['destroyed'] < time() - 300) {
// 通常不會發(fā)生這種情況。如果發(fā)生,那么可能是由于不穩(wěn)定的網(wǎng)絡狀況或者被攻擊導致的
// 移除用戶會話中的認證信息
remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
throw(new DestroyedSessionAccessException);
}
$old_sessionid = session_id();
// 設置會話銷毀時間戳
$_SESSION['destroyed'] = time(); // 從 PHP 7.0.0 開始, session_regenerate_id() 會自動保存會話數(shù)據(jù)
// 如果直接調(diào)用 session_regenerate_id() 函數(shù)可能會導致會話丟失的情況,
// 參見下面的例程
session_regenerate_id();
// 新創(chuàng)建的會話不需要時間戳
unset($_SESSION['destroyed']);
$new_sessionid = session_id();
echo "Old Session: $old_sessionid<br />";
echo "New Session: $new_sessionid<br />";
print_r($_SESSION);
?>
當前的會話模塊未能很好的處理在網(wǎng)絡不穩(wěn)定的時候?qū)е聲拋G失的場景。 你需要自行管理會話 ID 避免調(diào)用 session_regenerate_id 導致會話丟失。
示例 #2 Avoiding lost session by session_regenerate_id()
<?php
// 注意:下列不是完整的代碼,只是一個示例
// my_session_start() 和 my_session_regenerate_id()
// 函數(shù)可以避免在網(wǎng)絡不穩(wěn)定的情況下導致會話丟失的問題。
// 并且還可以避免用戶會話被攻擊者利用
function my_session_start() {
session_start();
if (isset($_SESSION['destroyed'])) {
if ($_SESSION['destroyed'] < time()-300) {
// 通常不會發(fā)生這種情況。如果發(fā)生,那么可能是由于不穩(wěn)定的網(wǎng)絡狀況或者被攻擊導致的
// 移除用戶會話中的認證信息
remove_all_authentication_flag_from_active_sessions($_SESSION['userid']);
throw(new DestroyedSessionAccessException);
}
if (isset($_SESSION['new_session_id'])) {
// 尚未完全過期,可能是由于網(wǎng)絡不穩(wěn)定引起的。
// 嘗試再次設置正確的會話 ID cookie。
// 注意:如果你需要移除認證標記,那么不要嘗試再次設置會話 ID。
session_commit();
session_id($_SESSION['new_session_id']);
// 現(xiàn)在有了新的會話 ID 了。
session_start();
return;
}
}
}
function my_session_regenerate_id() {
// 如果由于不穩(wěn)定的網(wǎng)絡導致沒有創(chuàng)建會話 ID,
// 那么就創(chuàng)建一個
$new_session_id = session_create_id();
$_SESSION['new_session_id'] = $new_session_id;
// 設置銷毀時間戳
$_SESSION['destroyed'] = time();
// 保存并關(guān)閉會話
session_commit();
// 使用新的會話 ID 開始會話
session_id($new_session_id);
ini_set('session.use_strict_mode', 0);
session_start();
ini_set('session.use_strict_mode', 1);
// 新的會話不需要這 2 個數(shù)據(jù)了
unset($_SESSION['destroyed']);
unset($_SESSION['new_session_id']);
}
?>