登录系统生成的PHP空会话文件
最近,我注意到许多空白会话正在创建,我不知道为什么,因为我相信我做每件事都是正确的 当用户登录或注册时,我们创建会话,然后检查用户是否使用属于登录或注册期间创建的会话的登录系统生成的PHP空会话文件,php,session,cookies,Php,Session,Cookies,最近,我注意到许多空白会话正在创建,我不知道为什么,因为我相信我做每件事都是正确的 当用户登录或注册时,我们创建会话,然后检查用户是否使用属于登录或注册期间创建的会话的isset($\u COOKIE['auth'])登录 如果存在cookie,那么我们就启动一个会话,这有助于我们避免为未注册用户启动数千个会话,并创建大量会话文件 会话设置: php文件 php.ini 创建登录会话(成功登录时) 检查是否应恢复会话 然后,我们根据是否设置了auth会话cookie来检查是否为用户启动会话
isset($\u COOKIE['auth'])
登录
如果存在cookie,那么我们就启动一个会话,这有助于我们避免为未注册用户启动数千个会话,并创建大量会话文件
会话设置:
php文件
php.ini
创建登录会话(成功登录时)
检查是否应恢复会话 然后,我们根据是否设置了
auth
会话cookie来检查是否为用户启动会话
仅当用户在以下情况之前已注册或登录时才会设置:
if(isset($_COOKIE['auth'])){
session_start();
session_write_close();
}
检查用户是否已登录 为了检查用户是否登录,我们使用以下功能:
function isAuthenticated(){
if (!isset($_SESSION['userId']))
return false;
else
return true;
}
注销
function logOut(){
session_start();
session_destroy();
setcookie('auth', "", 0);
unset($_SESSION);
unset($_COOKIE['auth']);
return true;
}
由于某些原因,尽管我在会话文件夹中得到了很多空的(文件大小为0)会话文件 这些是从哪里来的
session\u regenate\u id(true)
是否创建新会话文件并将旧会话文件保留为空?这是我能想到的空会话文件的唯一原因?不应该头(“位置:$\u服务器[HTTP\u引用]”代码>需要是标题(“位置:$\u服务器['HTTP\u REFERER']”)代码>?或者这只是一些愚蠢的事情
编辑:
根据PHP.net,您应该使用delete\u old\u session
参数。看一看
查看以获取更多信息
session\u regenate\u id()
将用新会话id替换当前会话id,并保留当前会话信息
每次运行session\u register\u id()session\u register\u id()
使用新会话id创建新会话,但保留旧会话信息,因此是的,session\u register\u id()
在将信息更新到新会话文件后将旧会话文件保持为空。仅我的2美分:用户(无论是否登录)在特定时间内使用网站,通常称为“会话”。总是启动一个会话并保留一个会话变量以查看某人是否经过身份验证,这是否是一个问题。现在,您似乎只尝试在有人登录的情况下启动会话,这比仅启动会话并检查变量的相同行为增加了更多开销
如果将会话超时保持在较低水平,则会有人自动注销。根据站点流量,您可以将GC设置为更频繁或更不频繁地启动。(见:)
如果硬盘是会话的瓶颈(empy会话文件太多等),请创建一个小的RAMdisk来存储会话信息
会话\重新生成\ id(true)是否创建新会话文件并离开
旧会话文件是否为空?这是我能想到的唯一理由
空会话文件
调用session\u regenate\u id(true)
尝试删除会话文件,但如果失败,将返回false(请参阅下面的相关php源代码)。因此,我建议您验证会话功能是否成功运行,即
if(!session_start()) {
//log error
}
if(!session_regenerate_id(true)) {
//log error
}
还要检查垃圾收集器运行频率的设置。也许它运行的概率很低,您会看到孤立会话的累积。下面的设置将在每次php运行时以1/100(1%)的概率运行垃圾收集器。尝试删除所有孤立项,方法是在一次运行中将两个值都设置为1,然后将值设置为1/100,如下所示
session.gc_probability = 1
session.gc_divisor = 100
最后,您的注销方法将在浏览器关闭时终止会话cookie。请尝试立即将其过期
setcookie('auth', null, -1);
会话\u重新生成\u id的PHP源代码
注意调用PS(mod)->s\u destroy(&PS(mod\u数据),PS(id)TSRMLS\u CC)
PS\u DESTROY\u FUNC
注意VCWD\u UNLINK
,这是一个从磁盘删除文件的命令
PS_DESTROY_FUNC(files)
{
char buf[MAXPATHLEN];
PS_FILES_DATA;
if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return FAILURE;
}
if (data->fd != -1) {
ps_files_close(data);
if (VCWD_UNLINK(buf) == -1) {
/* This is a little safety check for instances when we are dealing with a regenerated session
* that was not yet written to disk. */
if (!VCWD_ACCESS(buf, F_OK)) {
return FAILURE;
}
}
}
return SUCCESS;
}
是的,gc应该更好地处理它,但是如果您调用创建会话id的函数,那么您就是在创建会话。只需调用SISTHORY销毁,如果它们未被认证。是代码> SeStudi.AutoMyStase= 0 ?您应该考虑将<代码> unSET($yScript)< /C> >通过<代码> Frace> /Cord>单独地对每个元素进行取消设置。“注意:不要用unSET($ysession)取消整个$i会话,因为这将禁止通过$$会话超全局来注册会话变量。”您的函数似乎处于假定状态,您必须始终保持虚拟状态,并始终检查。。总是向下投票????????????????非常愚蠢,真是白痴,哇+因为我想给出同样的答案。不能使用未定义的常量代替字符串。除此之外,它还允许头部注入,这是一个很大的安全问题。但最好这样使用:标题(“位置:”.$\u服务器['HTTP\u REFERER'])代码>我设置了一个演示为什么这个答案很重要:正如您在手册中看到的,将true传递给这个函数将删除旧的会话文件。
if(!session_start()) {
//log error
}
if(!session_regenerate_id(true)) {
//log error
}
session.gc_probability = 1
session.gc_divisor = 100
setcookie('auth', null, -1);
/* {{{ proto bool session_regenerate_id([bool delete_old_session])
Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session. */
static PHP_FUNCTION(session_regenerate_id)
{
zend_bool del_ses = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
return;
}
if (SG(headers_sent) && PS(use_cookies)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
RETURN_FALSE;
}
if (PS(session_status) == php_session_active) {
if (PS(id)) {
if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
RETURN_FALSE;
}
efree(PS(id));
PS(id) = NULL;
}
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
if (PS(id)) {
PS(send_cookie) = 1;
php_session_reset_id(TSRMLS_C);
RETURN_TRUE;
} else {
PS(id) = STR_EMPTY_ALLOC();
}
}
RETURN_FALSE;
}
PS_DESTROY_FUNC(files)
{
char buf[MAXPATHLEN];
PS_FILES_DATA;
if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return FAILURE;
}
if (data->fd != -1) {
ps_files_close(data);
if (VCWD_UNLINK(buf) == -1) {
/* This is a little safety check for instances when we are dealing with a regenerated session
* that was not yet written to disk. */
if (!VCWD_ACCESS(buf, F_OK)) {
return FAILURE;
}
}
}
return SUCCESS;
}