session_create_id()
(PHP 7 >= 7.1.0)
创建新的会话ID
说明
session_create_id([string $prefix]): string
session_create_id()用于为当前会话创建新的会话ID。它返回无冲突会话ID。如果会话未激活,则省略冲突检查。会话ID是根据php.ini设置创建的。对于GC任务脚本,请使用与Web服务器相同的用户ID,这一点很重要。否则,您可能会遇到权限问题,尤其是文件保存处理程序。
参数
- $prefix
If$prefixis specified, new session id is prefixed by$prefix. Not all characters are allowed within the session id. Characters in the rangea-z A-Z 0-9 ,(comma)and -(minus)are allowed.
返回值
session_create_id()返回当前会话的新的无冲突会话ID。如果在没有活动会话的情况下使用它,则将省略冲突检查。
范例
Example #1session_create_id()example withsession_regenerate_id()
<?php // My session start function support timestamp management function my_session_start() { session_start(); // Do not allow to use too old session ID if (!empty($_SESSION['deleted_time']) && $_SESSION['deleted_time'] < time() - 180) { session_destroy(); session_start(); } } // My session regenerate id function function my_session_regenerate_id() { // Call session_create_id() while session is active to // make sure collision free. if (session_status() != PHP_SESSION_ACTIVE) { session_start(); } // WARNING: Never use confidential strings for prefix! $newid = session_create_id('myprefix-'); // Set deleted timestamp. Session data must not be deleted immediately for reasons. $_SESSION['deleted_time'] = time(); // Finish session session_commit(); // Make sure to accept user defined session ID // NOTE: You must enable use_strict_mode for normal operations. ini_set('session.use_strict_mode', 0); // Set new custom session ID session_id($newid); // Start with custom session ID session_start(); } // Make sure use_strict_mode is enabled. // use_strict_mode is mandatory for security reasons. ini_set('session.use_strict_mode', 1); my_session_start(); // Session ID must be regenerated when // - User logged in // - User logged out // - Certain period has passed my_session_regenerate_id(); // Write useful codes ?>
参见
session_regenerate_id()
使用新生成的会话 ID 更新现有会话 IDsession_start()
启动新会话或者重用现有会话- session.use_strict_mode
- SessionHandler::create_sid()Return a new session ID
I needed to use session_create_id for the $prefix. I used the 'create_sid' handler in session_set_save_handler and it done all the magic for me. I could continue to use session_regenerate_id(); function sessionCreateHandler() { $prefix = 'bla'; return session_create_id($prefix); }
This function is very hard to replicate precisely in userland code, because if a session is already started, it will attempt to detect collisions using the new "validate_sid" session handler callback, which did not exist in earlier PHP versions.
If the handler you are using implements the "create_sid" callback, collisions may be detected there. This is called when you use session_regenerate_id(), so you could use that to create a new session, note its ID, then switch back to the old session ID. If no session is started, or the current handler doesn't implement "create_sid" and "validate_sid", neither this function nor session_regenerate_id() will guarantee collision resistance anyway.
If you have a suitable definition of random_bytes (a library is available to provide this for versions right back to PHP 5.3), you can use the following to generate a session ID in the same format PHP 7.1 would use. $bits_per_character should be 4, 5, or 6, corresponding to the values of the session.hash_bits_per_character / session.sid_bits_per_character ini setting. You will then need to detect collisions manually, e.g. by opening the session and confirming that $_SESSION is empty.
<?php
function 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);
// The below is translated from function bin_to_readable in the PHP source (ext/session/session.c)
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 {
// Should never happen. Input must be large enough.
break;
}
}
// consume $bits_per_character bits
$out .= $hexconvtab[$w & $mask];
$w >>= $bits_per_character;
$have -= $bits_per_character;
}
return $out;
}
?>