php 这是销毁php中所有会话数据的正确方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1226040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is this a proper way to destroy all session data in php?
提问by bbtang
Got it from php.net, but I am not sure is this how everybody destroy all sessions?
从 php.net 得到它,但我不确定这是不是每个人都销毁所有会话的方式?
// Unset all Sessions
$_SESSION = array();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() -42000, '/');
}
session_destroy();
Does the code will destroy all the sessions?? Is it the most common way? how do you guys destroy php sessions?
代码是否会破坏所有会话?这是最常见的方式吗?你们如何破坏php会话?
Oh yeah, btw, what is that session_name()? All session name? e.g $_SESSION['var1'], $_SESSION['var2'], ... ?
哦,是的,顺便说一句,那是session_name()什么?所有会话名称?例如$_SESSION['var1'], $_SESSION['var2'], ... ?
I dont need to use unset($_SESSION['var1']);any more right?
我不需要再用unset($_SESSION['var1']);了吧?
Whats the different between using session_destroy()and unset($_SESSION[])?
usingsession_destroy()和 有什么不同unset($_SESSION[])?
回答by Gumbo
You should first know what sessions are: You can consider sessions as a data container on the server side that's associated with a random identifier, the session ID. That session ID needs to be provided by the client so that the server can load the data associated to that session ID (and thus to that session) into the $_SESSIONvariable. Everything in that $_SESSIONvariable is also called session variablesof the current active session.
您应该首先知道什么是会话:您可以将会话视为服务器端的数据容器,它与随机标识符(会话 ID)相关联。该会话 ID 需要由客户端提供,以便服务器可以将与该会话 ID(进而与该会话)关联的数据加载到$_SESSION变量中。该$_SESSION变量中的所有内容也称为当前活动会话的会话变量。
Now to your questions:
现在回答你的问题:
Does the code will destroy all the sessions?? Is it the most common way? how do you guys destroy php sessions??
代码是否会破坏所有会话?这是最常见的方式吗?你们如何破坏php会话?
The provided code just deletes the session data of the current session. The $_SESSION = array();statement will simply reset the session variable $_SESSIONso that a future access on the session variable $_SESSIONwill fail. But the session container itself is not deleted yet. That will be done by calling session_destroy.
提供的代码只是删除当前会话的会话数据。该$_SESSION = array();语句将简单地重置会话变量,$_SESSION以便将来对会话变量的访问$_SESSION将失败。但是会话容器本身还没有被删除。这将通过调用来完成session_destroy。
See also Truly destroying a PHP Session?
另请参阅真正破坏 PHP 会话?
Oh yeah, btw, what is that session_name()?? All session name? e.g $_SESSION['var1'], $_SESSION['var2']... ?
哦,是的,顺便说一句,session_name() 是什么??所有会话名称?例如 $_SESSION['var1'], $_SESSION['var2']... ?
The session_nameis just used to identify the session ID parameter passed in a cookie, the URL's query or via a POST parameter. PHP's default value is PHPSESSID. But you can change it to whatever you want to.
该会话名称只是用来识别一个Cookie,URL查询或通过POST参数传递会话ID参数。PHP 的默认值为PHPSESSID. 但是您可以将其更改为您想要的任何内容。
I dont need to use unset($_SESSION['var1']); any more right???
我不需要使用 unset($_SESSION['var1']); 还有吗???
No. The initial $_SESSION = array();deletes all the session data.
否。初始$_SESSION = array();删除所有会话数据。
Whats the different between using session_destroy and unset($_SESSION[])??
使用 session_destroy 和 unset($_SESSION[]) 有什么不同??
session_destroywill delete the whole session container while unsetor resetting the $_SESSIONvariable will only delete the session data for the current runtime.
session_destroy将删除整个会话容器,而unset重置$_SESSION变量将仅删除当前运行时的会话数据。
回答by Marius
This only destroys the current users session, not all the other users session.
这只会破坏当前用户会话,而不是所有其他用户会话。
Try using the session_save_path() to find out where the session data is being stored, and then delete all the files there.
尝试使用 session_save_path() 找出会话数据的存储位置,然后删除那里的所有文件。
回答by Greg
session_name()is the name that's passed in the cookie / querystring. It's normally PHPSESSIDbut can be changed.
session_name()是在 cookie / 查询字符串中传递的名称。它通常是PHPSESSID,但可以更改。
There's no proper way to destroy all sessions.
As @Marius says, you could try deleting the session files from session_save_path()but that's a hack at best.
没有正确的方法来销毁所有会话。正如@Marius 所说,您可以尝试从中删除会话文件,session_save_path()但这充其量只是一种黑客攻击。
Alternatively you could use session_set_save_handler()to save your sessions to somewhere you have more control over, such as a database.
或者,您可以使用session_set_save_handler()将会话保存到您有更多控制权的地方,例如数据库。
回答by Mez
To destroy a single session, you should use the following:-
要销毁单个会话,您应该使用以下内容:-
session_destroy();
Assuming you've used session_start() to previously start/resume a session.
假设您已经使用 session_start() 之前启动/恢复会话。
Destroying all sessions really depends on your setup, and how you're handling sessions.
销毁所有会话实际上取决于您的设置以及您处理会话的方式。
For most PHP installs, the session handling is done via files, so the best way would be to find the folder that keeps all the sessions (usually found from session_save_path()), and delete all the files under that.
对于大多数 PHP 安装,会话处理是通过文件完成的,因此最好的方法是找到保存所有会话的文件夹(通常从 session_save_path() 中找到),并删除该文件夹下的所有文件。
I think though, the best way to handle this might be to pre-emptively set a timestamp in each session you create. This means that you can then compare that timestamp to a set point (the time when you want to invalidate all sessions) and invalidate the session if it's before that time. This also means that you can do things like set a specific timeout for a session, etc etc.
不过,我认为,处理此问题的最佳方法可能是在您创建的每个会话中预先设置时间戳。这意味着您随后可以将该时间戳与设置点(您希望使所有会话无效的时间)进行比较,并在该时间之前使会话无效。这也意味着您可以执行诸如为会话设置特定超时等操作。
Another way might be to change to use Database Stored Sessions - you can find a good tutorial for this here
另一种方法可能是更改为使用数据库存储会话 - 你可以在这里找到一个很好的教程
回答by we.mamat
i know this is an old thread...but i just wanted to share :)
我知道这是一个旧线程...但我只是想分享:)
i found out that instead of using a temp folder for the session you could save it into a database. so technically, management of sessions is possible.
我发现您可以将其保存到数据库中,而不是为会话使用临时文件夹。所以从技术上讲,会话管理是可能的。
My Code:
我的代码:
(mostly plaigiarised from http://www.tonymarston.net/php-mysql/session-handler.html#session.handler):
(主要来自http://www.tonymarston.net/php-mysql/session-handler.html#session.handler):
mysql:
mysql:
CREATE TABLE `php_session` (
`session_id` varchar(32) NOT NULL default '',
`user_id` varchar(16) default NULL,
`date_created` datetime NOT NULL default '0000-00-00 00:00:00',
`last_updated` datetime NOT NULL default '0000-00-00 00:00:00',
`session_data` longtext,
PRIMARY KEY (`session_id`),
KEY `last_updated` (`last_updated`)
)
the session handler (i put it in a separate file called php_session.class.php):
会话处理程序(我将它放在一个名为 php_session.class.php 的单独文件中):
<?php
class php_Session
{
// ****************************************************************************
// This class saves the PHP session data in a database table.
// ****************************************************************************
// ****************************************************************************
// class constructor
// ****************************************************************************
function php_Session ()
{
} // php_Session
// ****************************************************************************
function open ($save_path, $session_name)
// open the session.
{
// do nothing
return TRUE;
} // open
// ****************************************************************************
function close ()
// close the session.
{
if (!empty($this->fieldarray)) {
// perform garbage collection
$result = $this->gc(ini_get('session.gc_maxlifetime'));
// $result = ini_set('session.gc_maxlifetime',0);
return $result;//$result
} // if
return FALSE;
} // close
// ****************************************************************************
function read ($session_id)
// read any data for this session.
{
// $fieldarray = $this->_dml_getData("session_id='" .addslashes($session_id) ."'");
$fieldarray=array();
$data= mysql_query("select * from php_session where session_id='" .addslashes($session_id) ."'")or die(mysql_error());
while($row = mysql_fetch_array($data)) $fieldarray[]=$row;
if (isset($fieldarray[0]['session_data'])) {
$this->fieldarray = $fieldarray[0];
$this->fieldarray['session_data'] = '';
return $fieldarray[0]['session_data'];
} else {
return ''; // return an empty string
} // if
} // read
// ****************************************************************************
function write ($session_id, $session_data)
// write session data to the database.
{
if (!empty($this->fieldarray)) {
if ($this->fieldarray['session_id'] != $session_id) {
// user is starting a new session with previous data
$this->fieldarray = array();
} // if
} // if
if (empty($this->fieldarray)) {
// create new record
$a = $session_id;
$b = date("Y-m-d H:i:s");
$c = date("Y-m-d H:i:s");
$d = addslashes($session_data);
// $this->_dml_insertRecord($array);
mysql_query("insert into php_session (session_id,date_created,last_updated,session_data) values ('$a','$b','$c','$d')");
} else {
// update existing record
if (isset($_SESSION['login_id'])) {
$a = $_SESSION['login_id'];
} // if
$b = date("Y-m-d H:i:s");
$c = addslashes($session_data);
// $this->_dml_updateRecord($array, $this->fieldarray);
mysql_query("update php_session set last_updated='$b',session_data='$c',user_id='$a' where session_id='$session_id'");
$data= mysql_query("select * from php_session where session id='" .addslashes($session_id) ."'");
while($row = mysql_fetch_array($data)) $fieldarray[]=$row;
$this->fieldarray = $fieldarray[0];
} // if
return TRUE;
} // write
// ****************************************************************************
function destroy ($session_id)
// destroy the specified session.
{
$fieldarray['session_id'] = $session_id;
mysql_query("delete from php_session where session_id='$session_id'");
return TRUE;
} // destroy
// ****************************************************************************
function gc ($max_lifetime)
// perform garbage collection.
{
$real_now = date('Y-m-d H:i:s');
$dt1 = strtotime("$real_now -$max_lifetime seconds");
$dt2 = date('Y-m-d H:i:s', $dt1);
// $count = $this->_dml_deleteSelection("last_updated < '$dt2'");
mysql_query("delete from php_session where last_updated < '$dt2'");
$count = mysql_affected_rows();
return TRUE;
} // gc
// ****************************************************************************
function __destruct ()
// ensure session data is written out before classes are destroyed
// (see http://bugs.php.net/bug.php?id=33772 for details)
{
@session_write_close();
} // __destruct
// ****************************************************************************
}
?>
sorry for the messy code there.
抱歉那里的代码很乱。
To Use
使用
IMPORTANT :put before calling session_start()
重要:在调用 session_start() 之前放置
require_once 'php_session.class.php';
$session_class = new php_Session;
session_set_save_handler(array(&$session_class, 'open'),
array(&$session_class, 'close'),
array(&$session_class, 'read'),
array(&$session_class, 'write'),
array(&$session_class, 'destroy'),
array(&$session_class, 'gc'));
then call in session_start() and your done!
然后调用 session_start() 就完成了!
Since its in mysql, you could see who's online via user id (which is set yourself using $_SESSION), and perform functions like logging them out and stuff (thats what im using it for).
由于它在 mysql 中,您可以通过用户 ID(使用 $_SESSION 自行设置)查看谁在线,并执行诸如注销之类的功能(这就是我使用它的目的)。
回答by mr.baby123
You will have to delete the session records.
您将不得不删除会话记录。
if session handled by DB- delete the rows.
if session handled by FILES- delete the files.
如果会话由DB处理- 删除行。
如果会话由文件处理- 删除文件。
here you can find full example:
在这里你可以找到完整的例子:
http://mdb-blog.blogspot.co.il/2015/05/php-destroydelete-all-sessions.html
http://mdb-blog.blogspot.co.il/2015/05/php-destroydelete-all-sessions.html
回答by Daniel
The easiest way is not to delete all sessions at once, but to remember your last login and timestamp of the session reset.
最简单的方法不是一次删除所有会话,而是记住您上次登录和会话重置的时间戳。
//Start your session
session_start();
//Get your stored timestamp of reset
//(i.e. stored in database)
$timestamp_reset = ...
//Get your stored timestamp of your session
//(i.e. store it in session or database when you log in)
$timestamp_session = ...
//See if the login was before the reset timestamp
if ( $timestamp_reset > $timestamp_session ) {
//Reset you session and go on
session_unset();
}
It will not remove all session files, but will prevent old sessions running. And you do not have to rely on the garbage collector. Didn't find a similar answer here so I had to add this one. Have a nice day.
它不会删除所有会话文件,但会阻止旧会话运行。而且您不必依赖垃圾收集器。在这里没有找到类似的答案,所以我不得不添加这个。祝你今天过得愉快。
To your further questions:
对于您的进一步问题:
Your code will only destroy your single session and is the most common way to i.e. sign out.
您的代码只会破坏您的单个会话,并且是最常见的退出方式。
session_name will give you the name of the variable, php uses for cookie exchange, you'll not need that most of the time. The code that is used in your example is a very old one, please do not use this.
session_name 将为您提供变量的名称,php 用于 cookie 交换,大多数情况下您不需要。您的示例中使用的代码是非常旧的代码,请不要使用它。
You do not have to unset every single array item by unset if you use session_destroy or session_unset.
如果使用 session_destroy 或 session_unset,则不必通过 unset 来取消设置每个数组项。
unset($_SESSION) will not work.
unset($_SESSION) 将不起作用。
回答by Fabian Horlacher
To remove all session files from PHP, you can use this function:
要从 PHP 中删除所有会话文件,您可以使用此函数:
<?php
/**
* Hack to destroy all PHP session files
*
* @param string $prefixSessionFile Prefix of the session filename
* @param int|null|false $sessionIdLength Expected Length of the session ID in the session filename. null: Determine automatically. false: do not check
*
* @return int Removed sessions
* @throws Exception
*/
function destroyAllPhpSessionFiles($prefixSessionFile = 'sess_', $sessionIdLength = 26)
{
if (session_status() === PHP_SESSION_DISABLED) {
throw new Exception('Session handling is disabled');
}
if ($sessionIdLength === null) {
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
$sessionIdLength = strlen(session_id());
}
// Allow to remove current session
session_abort();
// Get session dir
if (!$sessionDir = session_save_path()) {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// Windows
$sessionDir = sys_get_temp_dir();
// If this script is called from a user (example in cmd), but your server uses the system environment variable (system-wide temp dir):
//$sessionDir = system('echo %windir%') . DIRECTORY_SEPARATOR . 'Temp';
} elseif (is_dir('/var/lib/php5')) {
// Ubuntu or Debian
$sessionDir = '/var/lib/php5';
} elseif (is_dir('/var/lib/php/session')) {
// RHEL or CentOS
$sessionDir = '/var/lib/php/session';
}
if (!$sessionDir || !is_dir($sessionDir)) {
$sessionDir = sys_get_temp_dir();
}
}
// Drop session files
$files = scandir($sessionDir);
$sessionsDeleted = 0;
$prefixLength = strlen($prefixSessionFile);
$filenameLength = $prefixLength + $sessionIdLength;
foreach ($files AS $file) {
if (substr($file, 0, $prefixLength) != $prefixSessionFile) {
// Prefix does not fit
continue;
}
if ($sessionIdLength && strlen($file) != $filenameLength) {
// Filename length does not fit
continue;
}
$path = $sessionDir . DIRECTORY_SEPARATOR . $file;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// Windows
exec('DEL ' . $path);
} else {
// Linux / Unix
shell_exec('rm -f ' . $path);
}
if (is_file($path)) {
throw new Exception('Could not delete session file ' . $path);
}
$sessionsDeleted++;
}
return $sessionsDeleted;
}
回答by aldosa
If you want to avoid the warning:
如果你想避免警告:
Warning: session_destroy(): Trying to destroy uninitialized session in ... on line 18
警告:session_destroy():试图在第 18 行销毁未初始化的会话...
Don't forget to add session_start();to the beginning of your code. Other than that the code you provided works as intended.
不要忘记添加session_start();到代码的开头。除此之外,您提供的代码按预期工作。

