PHP 8.5.0 Alpha 1 available for testing

session_create_id

(PHP 7 >= 7.1.0, PHP 8)

session_create_idCrear un nuevo ID de sesión

Descripción

session_create_id(string $prefix = ""): string|false

session_create_id() se utiliza para crear un nuevo ID de sesión para la sesión actual. Esto devuelve un ID de sesión sin colisión.

Si la sesión no está activa, la verificación de colisión se omite.

El ID de sesión se crea de acuerdo con los parámetros php.ini.

Es importante utilizar el mismo ID de usuario de su servidor web para el script de la tarea de Recogida de Basura (Garbage Collection). De lo contrario, se pueden tener problemas de permisos, especialmente con los gestores de guardado de ficheros.

Parámetros

prefix

Si prefix está especificado, el nuevo ID de sesión se prefiere con prefix. No todos los caracteres están permitidos en el ID de sesión. Los caracteres entre [a-z A-Z 0-9] están permitidos. La longitud máxima es de 256 caracteres.

Valores devueltos

session_create_id() devuelve un nuevo ID de sesión sin colisión para la sesión actual. Si se utiliza sin una sesión activa, la verificación de colisión se omite. En caso de error, false se devuelve.

Ejemplos

Ejemplo #1 Ejemplo de session_create_id() con session_regenerate_id()

<?php
// Mi función de inicio de sesión soporta la gestión de marcas de tiempo
function my_session_start() {
session_start();
// No permite el uso de antiguos ID de sesión
if (!empty($_SESSION['deleted_time']) && $_SESSION['deleted_time'] < time() - 180) {
session_destroy();
session_start();
}
}

// Mi función de regeneración de ID
function my_session_regenerate_id() {
// Llamada a session_create_id() cuando la sesión está activa
// para asegurarse de que no hay colisión.
if (session_status() != PHP_SESSION_ACTIVE) {
session_start();
}
// ADVERTENCIA: Nunca utilizar cadenas confidenciales como prefijo
$newid = session_create_id('myprefix-');
// Establece la marca de tiempo de eliminación.
// Los datos de sesión no deben eliminarse inmediatamente por ciertas razones.
$_SESSION['deleted_time'] = time();
// Termina la sesión
session_commit();
// Asegúrese de aceptar los ID de sesión definidos por el usuario
// NOTA: Debe activar use_strict_mode para operaciones normales.
ini_set('session.use_strict_mode', 0);
// Definir un nuevo ID de sesión personalizado
session_id($newid);
// Inicio con un ID de sesión personalizado
session_start();
}

// Asegúrese de que use_strict_mode esté activado.
// use_strict_mode es obligatorio por razones de seguridad.
ini_set('session.use_strict_mode', 1);
my_session_start();

// El ID de sesión debe regenerarse cuando
// - Un usuario se conecta
// - Un usuario se desconecta
// - Ha transcurrido un cierto período de tiempo
my_session_regenerate_id();

// Lógica de aplicación
?>

Ver también

add a note

User Contributed Notes 1 note

up
3
rowan dot collins at gmail dot com
7 years ago
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;
}
?>
To Top