这是破坏php中所有会话数据的正确方法吗?

时间:2009-08-04 07:08:09

标签: php session

从php.net得到它,但我不确定这是怎么会破坏所有会话的?

// Unset all Sessions
$_SESSION = array();

if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time() -42000, '/');
}

    session_destroy();

代码会破坏所有会话吗?这是最常见的方式吗?你们怎么破坏php会话?

哦,是的,顺便问一下,session_name()是什么?所有会话名称?例如$_SESSION['var1']$_SESSION['var2'],...?

我不需要再使用unset($_SESSION['var1']);了吗?

使用session_destroy()unset($_SESSION[])之间的区别是什么?

9 个答案:

答案 0 :(得分:21)

您首先应该知道会话是什么:您可以将会话视为服务器端的数据容器,该容器与随机标识符(会话ID)相关联。该会话ID需要由客户端提供,以便服务器可以将与该会话ID相关联的数据(以及因此该会话)加载到$_SESSION变量中。该$_SESSION变量中的所有内容也称为当前活动会话的会话变量

现在回答你的问题:

  

代码会破坏所有会话吗?这是最常见的方式吗?你们怎么破坏php会话?

提供的代码只删除当前会话的会话数据。 $_SESSION = array();语句只会重置会话变量$_SESSION,以便将来对会话变量$_SESSION的访问失败。但是会话容器本身尚未删除。这将通过调用session_destroy来完成。

另见Truly destroying a PHP Session?

  

哦是的,顺便说一句,那个session_name()是什么?所有会话名称?例如$ _SESSION ['var1'],$ _SESSION ['var2'] ......?

session_name仅用于标识cookie中传递的会话ID参数,URL的查询或POST参数。 PHP的默认值为PHPSESSID。但是你可以把它改成你想要的任何东西。

  

我不需要使用unset($ _ SESSION ['var1']);对了???

没有。初始$_SESSION = array();删除所有会话数据。

  

使用session_destroy和unset($ _ SESSION [])之间的区别是什么?

session_destroy将删除整个会话容器unset或重置$_SESSION变量只会删除当前运行时的会话数据。

答案 1 :(得分:12)

这只会破坏当前用户会话,而不会破坏所有其他用户会话。

尝试使用session_save_path()找出会话数据的存储位置,然后删除那里的所有文件。

答案 2 :(得分:2)

session_name()是cookie / querystring中传递的名称。它通常是 PHPSESSID ,但可以更改。

没有正确的方法来销毁所有会话。 正如@Marius所说,您可以尝试从session_save_path()删除会话文件,但这是最好的黑客攻击。

或者,您可以使用session_set_save_handler()将会话保存到您可以控制的地方,例如数据库。

答案 3 :(得分:2)

要销毁单个会话,您应该使用以下内容: -

session_destroy();

假设您已使用session_start()预先启动/恢复会话。

销毁所有会话实际上取决于您的设置以及您如何处理会话。

对于大多数PHP安装,会话处理是通过文件完成的,因此最好的方法是找到保存所有会话的文件夹(通常在session_save_path()中找到),并删除其下的所有文件。

我认为,处理此问题的最佳方法可能是在您创建的每个会话中预先设置时间戳。这意味着您可以将该时间戳与设定点(您希望使所有会话无效的时间)进行比较,并在该时间之前使会话无效。这也意味着您可以执行诸如为会话设置特定超时等操作。

另一种方法可能是更改为使用数据库存储会话 - 您可以找到一个很好的教程here

答案 4 :(得分:2)

我知道这是一个老线程...但我只是想分享:)

我发现不是使用临时文件夹进行会话,而是将其保存到数据库中。从技术上讲,会议管理是可能的。

我的代码:

(主要来自http://www.tonymarston.net/php-mysql/session-handler.html#session.handler):

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`)
)

会话处理程序(我把它放在一个名为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

// ****************************************************************************
}
?>

抱歉那里有凌乱的代码。

使用

重要提示:在调用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'));

然后调用session_start()并完成!

因为它在mysql中,您可以通过用户ID(使用$ _SESSION自行设置)查看谁在线,并执行登录和填充等功能(这就是我使用它的原因)。

答案 5 :(得分:1)

您必须删除会话记录。

  

如果会话由 DB 处理 - 删除行。

     

如果会话由 FILES 处理 - 删除文件。

在这里你可以找到完整的例子:

http://mdb-blog.blogspot.co.il/2015/05/php-destroydelete-all-sessions.html

答案 6 :(得分:0)

如果您想避免警告:

  

警告:session_destroy():尝试销毁未初始化的会话   ......第18行

不要忘记将session_start();添加到代码的开头。除此之外,您提供的代码按预期工作。

答案 7 :(得分:0)

最简单的方法是不要一次删除所有会话,而是要记住会话重置的上次登录和时间戳。

//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();
}

它不会删除所有会话文件,但会阻止旧会话运行。而且你不必依赖垃圾收集器。在这里没有找到类似的答案,所以我不得不添加这个。祝你有愉快的一天。

您的进一步问题:

您的代码只会破坏您的单个会话,并且是最常见的退出方式。

session_name将为您提供变量的名称,php用于cookie交换,您大部分时间都不需要。您的示例中使用的代码非常旧,请不要使用它。

如果使用session_destroy或session_unset,则不必通过取消设置取消设置每个数组项。

取消设置($ _ SESSION)将无效。

答案 8 :(得分:0)

要从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;
}