百科狗-知识改变命运!
--

session_id() - php 会话函数session

梵高12个月前 (11-21)阅读数 22#技术干货
文章标签函数

session_id()

(PHP 4, PHP 5, PHP 7)

获取/设置当前会话 ID

说明

session_id([string $id]): string

session_id() - php 会话函数session

session_id()可以用来获取/设置当前会话 ID。

为了能够将会话 ID 很方便的附加到 URL 之后,你可以使用常量SID获取以字符串格式表达的会话名称和 ID。请参考会话处理。

参数

$id

如果指定了$id参数的值,则使用指定值作为会话 ID。必须在调用session_start()函数之前调用session_id()函数。不同的会话管理器对于会话 ID 中可以使用的字符有不同的限制。例如文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 ,(逗号)和-(减号)

Note:如果使用 cookie 方式传送会话 ID,并且指定了$id参数,在调用session_start()之后都会向客户端发送新的 cookie,无论当前的会话 ID 和新指定的会话 ID 是否相同。

返回值

session_id()返回当前会话ID。如果当前没有会话,则返回空字符串("")。

参见

  • session_regenerate_id() 使用新生成的会话 ID 更新现有会话 ID
  • session_start() 启动新会话或者重用现有会话
  • session_set_save_handler() 设置用户自定义会话存储函数
  • session.save_handler
It may be good to note that PHP does not allow arbitrary session ids. The session id validation in PHP source is defined in ext/session/session.c in the function php_session_valid_key:
https://github.com/php/php-src/blob/master/ext/session/session.c
To put it short, a valid session id may consists of digits, letters A to Z (both upper and lower case), comma and dash. Described as a character class, it would be [-,a-zA-Z0-9]. A valid session id may have the length between 1 and 128 characters. To validate session ids, the easiest way to do it use a function like:

session_id() itself will happily accept invalid session ids, but if you try to start a session using an invalid id, you will get the following error:
Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'
session_id() URL-decodes the session value.  For example let's say we use setcookie() to push a cookie down to a web browser. When the browser makes the next page request the browser sends the cookie back up to us with headers like this: Cookie: PHPSESSID=enGHumY%2C-2De-F-TDzNHVmE%2ChY5;
If we use session_id() to read the cookie it will output a value of this: enGHumY,-2De-F-TDzNHVmE,hY5 
The two values don't match! Use either setrawcookie() or URL encode if you wish to match the original value.
If you look at the notes on cookies (set_cookie I think), you will see that you can not read a cookie on the page that it is set. That is because the cookies are sent with the page request which comes, of course, before your PHP is run. You have to wait until the next page request from the same source to read the cookie.
When session.use_strict_mode is set to 1 or true, you cannot use session_id($sid) to set the session id for the current session. 
I was perplexed by inconsistent results with the session ID depending on whether I retrieve it using SID, COOKIE, or session_id(). I have found that session_id() is the most reliable method, whereas SID and COOKIE["PHPSESSIONID"] are sometimes undefined.
I used this simple script to quickly test the problem on my servers:

Regardless of browser I see the COOKIE undefined on the first load and the other two defined, then SID is empty on subsequent reloads and COOKIE is defined, but session_id() is always defined.
If I insert the session_regenerate_id() method that jeff_zamrzla gives below the refresh the page, I get a new session_id() but the COOKIE value is initially the prior session_id() until I hit refresh a second time. So again, session_id() proves to be the most reliable method.
It's probably not a bug since I found the behaviour to be consistent in PHP versions 5.2.14, 5.3.3 and 5.3.4, but I can't figure what I'm missing and hopefully this will help others who run into this.
IMPORTANT NOTE:
If you assign a specific session ID to a user in your applet, then do not run the following code either while logout,
session_regenerate_id(TRUE);
USE:
session_regenerate_id();  instead.
OTHERWISE, setting the session id will no longer works for that user.
Regarding Colin's comment, note that setting hash_bits_per_character to 5 results in characters ranging from 0-9 and a-v. Most attackers would be wise enough to realize what was going on when they saw a letter in g-v. The probability of not seeing a letter in g-v is somewhere around 2^-32.
About the note from Cybertinus : 
The following test doesn't work, the code following is always executed : 
Note that Firefox and Mozilla use the same process for launching new windows or tabs, they will pick up the same session id as the previous windows until the parent process dies or is closed. This may cause undesired results if the session id is stored in a db and checked, a solution is to check at the new entry point (new tab or window if the user went back to the index page) for an existing session. If a session id exists and a new one is required use something like: 
The call session_id(null) and session_id() provides not the same result. It is imperative to pass no parameters to get correct results.
Gosh, took a LOOONG time to figure this one out! If you have suhosin built into your PHP and can't get sessions to work after changing the session id through session_id(), try turning off suhosin's session encryption option in php.ini with:
suhosin.session.encrypt=Off
The higher you set session.hash_bits_per_character the shorter your session_id will become by using more bits per character. The possible values are 4, 5, or 6.
When using sha-1 for hashing (by setting ini_set('session.hash_function', 1) the following session string lengths are produced by the three session.hash_bits_per_character settings:
4 - 40 character string
5 - 32 character string
6 - 27 character string 
It would seem desirable to use sha-l with 5 bits_per_character because this will emulate a standard 32 character md5 string and make a would-be attacker think that is what you're hashing with.
The documentation for session_id is incomplete when it says: 
"For example, the file session handler only allows characters in the range a-z, A-Z and 0-9!".
It is untrue when changing the default for the session.hash_bits_per_character as Colin said. session_id may therefore contain "-" and ",".
http://fr.php.net/manual/en/session.configuration.php
I had a lot of trouble with session_regenerate_id() as it did not regenerate... Session_id() stayed the same no matter what (unless closing the window). I wanted to have different sid and empty vars for each session/page meeting a condition for security reasons. Finally, this worked:
内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)