• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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 更新现有会话 ID
    • session_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;
    }
    ?>