©
本文档使用 PHP中文网手册 发布
通过为每个独立用户分配唯一的会话 ID,可以实现针对不同用户分别存储数据的功能。 会话通常被用来在多个页面请求之间保存及共享信息。 一般来说,会话 ID 通过 cookie 的方式发送到浏览器,并且在服务器端也是通过会话 ID 来取回会话中的数据。 如果请求中不包含会话 ID 信息,那么 PHP 就会创建一个新的会话,并为新创建的会话分配新的 ID。
会话的工作流程很简单。当开始一个会话时,PHP 会尝试从请求中查找会话 ID (通常通过会话 cookie), 如果请求中不包含会话 ID 信息,PHP 就会创建一个新的会话。 会话开始之后,PHP 就会将会话中的数据设置到 $_SESSION 变量中。 当 PHP 停止的时候,它会自动读取 $_SESSION 中的内容,并将其进行序列化, 然后发送给会话保存管理器器来进行保存。
默认情况下,PHP 使用内置的文件会话保存管理器(files
)来完成会话的保存。
也可以通过配置项 session.save_handler 来修改所要采用的会话保存管理器。
对于文件会话保存管理器,会将会话数据保存到配置项
session.save_path 所指定的位置。
可以通过调用函数 session_start() 来手动开始一个会话。
如果配置项 session.auto_start 设置为1
,
那么请求开始的时候,会话会自动开始。
PHP 脚本执行完毕之后,会话会自动关闭。 同时,也可以通过调用函数 session_write_close() 来手动关闭会话。
Example #1 在 $_SESSION 中注册变量。
<?php
session_start ();
if (!isset( $_SESSION [ 'count' ])) {
$_SESSION [ 'count' ] = 0 ;
} else {
$_SESSION [ 'count' ]++;
}
?>
Example #2 从 $_SESSION 中反注册变量。
<?php
session_start ();
unset( $_SESSION [ 'count' ]);
?>
千万不要使用 unset($_SESSION) 来复位超级变量 $_SESSION , 因为这样会导致无法继续在 $_SESSION 中注册会话变量。
由于无法将一个引用恢复到另外一个变量, 所以不可以将引用保存到会话变量中。
如果会话中存在和全局变量同名的变量,那么 register_globals 会导致全局变量被会话变量覆盖。 更多信息请参考 注册全局变量。
Note:
无论是通过调用函数 session_start() 手动开启会话, 还是使用配置项 session.auto_start 自动开启会话, 对于基于文件的会话数据保存(PHP 的默认行为)而言, 在会话开始的时候都会给会话数据文件加锁, 直到 PHP 脚本执行完毕或者显式调用 session_write_close() 来保存会话数据。 在此期间,其他脚本不可以访问同一个会话数据文件。
对于大量使用 Ajax 或者并发请求的网站而言,这可能是一个严重的问题。 解决这个问题最简单的做法是如果修改了会话中的变量, 那么应该尽快调用 session_write_close() 来保存会话数据并释放文件锁。 还有一种选择就是使用支持并发操作的会话保存管理器来替代文件会话保存管理器。
[#1] v888666 at 126 dot com [2015-08-28 13:52:24]
as metioned in 5th paragraph:
"Sessions normally shutdown automatically when PHP is finished executing a script, but can be manually shutdown using the session_write_close() function."
It's important to note that , "session shutdown " and "session invalid" are not equivalant. when a session shutdown, its session file is still valid in 24min by default (session file still exists in session path) .
In subsquent access to this site ( ensure that this session file still exists ) ,this session will be resumed by session_start().
[#2] eddie at onefoldmedia dot com [2014-01-02 05:20:19]
If a session is not saving and you have verified that session_start() is being called, then double check capitalization. $_session can store variables but will not be treated like a session or cause an error.
[#3] guy at syntheticwebapps dot com [2013-09-25 16:01:02]
Despite the warning about not being able to use references inside the session space, I've done it in the past and apparently completely successfully. That is, I can do something like this:
<?php
session_start();
if (!$_SESSION['favorite']) {
$_SESSION['cow'] = "Elsie";
$_SESSION['favorite'] =& $_SESSION['cow'];
echo "We set cow = '$_SESSION[cow]' and favorite =& cow ($_SESSION[favorite]).<br/>Reload the page to see if both change when one changes later.<br/>";
} else {
echo "Having re-entered the session after initial settings were made: cow = $_SESSION[cow] and favorite = $_SESSION[favorite].<br/>";
$_SESSION['cow'] = "Bessie";
echo "We reassigned cow = $_SESSION[cow] and our restored reference variable favorite = $_SESSION[favorite]<br/>Note the presence of the &s in the var_dump below.<pre>";
var_dump($_SESSION);
echo "</pre><br/>If you reload, the test will begin again.";
unset($_SESSION['cow'], $_SESSION['favorite']);
session_destroy();
}
?>
yields the following after the second request:
Having re-entered the session after initial settings were made: cow = Elsie and favorite = Elsie.
We reassigned cow = Bessie and our restored reference variable favorite = Bessie
Note the presence of the &s in the var_dump below.
array(2) {
["cow"]=>
&string(6) "Bessie"
["favorite"]=>
&string(6) "Bessie"
}
If you reload, the test will begin again.
I've found this ability very useful and storage efficient in the session data.
[#4] AlexFBP [2013-01-25 04:50:22]
Regardless, if you need to set the header 'Location:' before closing the session; explicitly close the php script with "exit()" or "die()" functions. Remember that when a php script ends, the session automatically are going to be closed.
[#5] jpleveille at webgraphe dot com [2012-09-07 18:06:36]
As mentioned in the documentation, using session_write_close() shuts down the session. It is particularly useful if you want to use header('Location: SOMEURL'); to a URL within the same scope of the current script, that will load the session. Why?
When you use this header directive, the browser is requested to redirect the user to the given URL. If that URL is in the scope of the script where header() is called (let's say, same URL), the requested URL "COULD" load the session BEFORE it has actually been shut down in the previous script, and you might end up with the session from the previous request, reverting all modifications to session in the the last script.
<?php
session_start();
if (!isset($_SESSION['hello']))
{
$_SESSION['hello'] = 'world';
session_write_close();
// session is now closed, it's safe to redirect
// if not closed, $_SESSION['hello'] may not be set properly
// when loading the page again
// (in this very case, calls to this script could loop for a while)
header('Location: ' . $_SERVER['PHP_SELF']);
}
?>