添加新的PHP会话变量正在破坏会话

时间:2013-10-22 10:07:30

标签: php variables session

我遇到了一个奇怪的问题,我希望有人能说清楚。 我有一个使用PHP会话存储登录详细信息的网站。在这个网站上是一个也使用PHP会话变量的游戏。每当我没有登录网站一段时间,然后尝试玩它记录我的游戏。如果我立即重新登录会话变量会被记住,我会保持登录状态,并且可以根据需要多次玩游戏。我可以访问网站上的任何其他页面而没有任何问题。

我在所有页面的顶部都有session_start。有什么想法吗?谢谢。

这是我的init.php文件:

    <?php
    ob_start();
    session_start();
   //error_reporting(0); // don't display errors

require 'database/connect.php'; 
require 'functions/general.php';
require 'functions/users.php';
require 'functions/items.php';
require 'functions/creatures.php';

$current_file = explode('/', $_SERVER['SCRIPT_NAME']);
$current_file = end($current_file);

if (logged_in() === true){
    $session_user_id = $_SESSION['user_id'];
    $user_data = user_data($session_user_id, 'user_id', 'username', 'password', 'first_name', 'last_name', 'email', 'password_recover', 'type', 'allow_email', 'profile', 'coins');
    $creature_data = creature_data($session_user_id, 'base_creature_id', 'level', 'strength', 'speed', 'intelligence', 'happiness', 'status', 'battle_level');


    if(user_active($user_data['username']) === false) {
        session_destroy();
        header('Location: logout.php');
        exit();
    }
    if($current_file !== 'changepassword.php' && $user_data['password_recover'] == 1){
        header('Location: changepassword.php?force');
        exit();
    }
}

$errors = array();

?>

以下是游戏文件:

<?php
require_once('core.php');
Hangman::StartPage();
?>
    <head>
        <link rel="stylesheet" type="text/css" href="games/plank/styles.css" />
    </head>
        <?php Hangman::PrintGameState(); ?>
        <div id="content">
            <!--<div id="banner"><img src="games/plank/images/interface/banner.png" /></div>-->
            <div id="innerContent">
                <div id="wordArea">
                    <span class="alphabet">
                        <?php Hangman::PrintCurrentWord(); ?>
                    </span>
                </div>

                <span id="controls">

                    <?php if(isset($_GET['finished']) === true && empty($_GET['finished']) === true){ ?>
                        <img id="result" src="games/plank/images/interface/<?php echo Hangman::GameResult() ? 'win' : 'lose'; ?>.png" />

                        <a id="replay" href="http://www.mobbipets.com/site/walkthepalm.php?m=r"></a>
                    <?php } 
                    else if (Hangman::IsGameFinished()) {
                        header('Location: walkthepalm.php?finished'); 
                            if (Hangman::GameResult() == 'win'){
                                update_coins($session_user_id, 50); 
                                 } 
                        } 

                    else { ?>
                    <span class="alphabet">
                        <?php Hangman::PrintKeyboard(); ?>
                    </span>
                    <?php } ?>
                </span>
                <span id="hangman"><img src="games/plank/images/hangman/<?php echo $_SESSION['gameState']; ?>.png" /></span>
            </div>
        </div>

<?php Hangman::EndPage(); ?>

这是游戏使用的core.php文件。

<?php
require_once('db.php');
/*=================================================
    this class handles game logic and php sessions.
==================================================*/
abstract class Hangman
{
    private static $pageUrl = 'http://www.mobbipets.com/site/walkthepalm.php';
    private static $gameStates = 8; //includes the game over state
    private static $keyboardButtons = "abcdefghijklmnopqrstuvwxyz&'-";
    private static $underscores = array(
        'us_1',
        'us_2',
        'us_3',
        );
    private static $alphabetAliases = array(
        '&' => 'amp',
        '\'' => 'apos',
        '-' => 'hyphen',
        ',' => 'comma',
        '!' => 'exclaim',
        '+' => 'plus',
        '?' => 'question',
        );

    //just checks if we have a valid session
    public static function IsLoggedIn()
    {
        if(isset($_SESSION['valid']) && $_SESSION['valid'])
            return true;
        return false;
    }

    private static function RegenerateSession()
    {
        //session_regenerate_id();
        $_SESSION['valid'] = 1;
        $_SESSION['lastActivity'] = time();
        $_SESSION['word'] = Database::GetRandomWord();
        $_SESSION['lettersLeft'] = strlen($_SESSION['word']);
        $_SESSION['guessedLetters'] = '';
        $_SESSION['gameState'] = 1;
    //  $session_user_id = $_SESSION['user_id'];
    }

    //session handling
    public static function StartPage()
    {
        //session_start();

        //terminate the session if we've been inactive for more than 10 minutes
        if (self::IsLoggedIn())
        {
            if (isset($_SESSION['lastActivity']) && ((time() - $_SESSION['lastActivity']) > 600 ))
                self::EndSession();
            else
                $_SESSION['lastActivity'] = time();
        } 

        //if logged in after timeout check
        if (self::IsLoggedIn())
        {
            $mode = trim(@$_GET['m']);
            if ($mode != '')            
                $mode = strtolower($mode);

            if ($mode != '') //we've passed a special input 'mode'
            {
                switch ($mode)
                {
                    case 'g': //player making a guess
                        $guess = trim(@$_GET['g']);
                        if ($guess != '')
                        {
                            $guess = self::FromAlias(strtolower($guess));
                            if (strlen($guess) == 1 && stripos($_SESSION['guessedLetters'],$guess) === false) //valid
                            {
                                $_SESSION['guessedLetters'] .= $guess;
                                if (stripos($_SESSION['word'],$guess) === false) //wrong guess
                                    $_SESSION['gameState']++;
                                else
                                    $_SESSION['lettersLeft'] -= substr_count($_SESSION['word'] ,$guess);
                            }
                        }
                        break;

                    case 'r': //forced reset of session
                        self::EndSession();
                        break;
                }
            }
        }

        //we forced a reset
        if (!self::IsLoggedIn())
        {
            self::RegenerateSession();
            header ('Location: '.self::$pageUrl); 
        }
    } 


    //is the game finished
    public static function IsGameFinished()
    {
        return $_SESSION['gameState'] >= self::$gameStates || (isset($_SESSION['lettersLeft']) && $_SESSION['lettersLeft'] <= 0);
    }

    //check if we won (true == win)
    public static function GameResult()
    {
        return $_SESSION['gameState'] < self::$gameStates && $_SESSION['lettersLeft'] == 0;
    }

    //add any page-close stuff here
    public static function EndPage()
    {

    }

    //terminates the session
    private static function EndSession()
    {
        //$_SESSION = array(); //destroy all of the session variables
        //session_destroy();
        //session_unset();
        self::RegenerateSession();
        return true;
    }

    //convert a character to it's alias
    private static function ToAlias($letter)
    {
        return array_key_exists($letter, self::$alphabetAliases) ? self::$alphabetAliases[$letter] : $letter;
    }

    //reduce an alias to it's corresponding character
    private static function FromAlias($alias)
    {
        $key = array_search($alias, self::$alphabetAliases);
        return $key === false ? $alias : $key;
    }

    //spit out the current word images based on game state
    public static function PrintCurrentWord()
    {
        if (!self::IsLoggedIn())
            return;

        $finished = self::IsGameFinished();

        for ($i = 0; $i < strlen($_SESSION['word']); $i++)
        {
            $letter = substr($_SESSION['word'],$i,1);
            echo '<span class="';
            if (!$finished && stripos($_SESSION['guessedLetters'], $letter) === false) //haven't guessed this yet
                echo self::$underscores[rand(0,count(self::$underscores)-1)];
            else //is a valid character that we've guessed already
                echo self::ToAlias($letter);
            echo '"></span>'."\n";
        }
    }

    public static function PrintGameState() //debugging
    {
        echo "\n<!--\n";
        echo "Word: ".$_SESSION['word']."\n";
        echo "Letters guessed: ".$_SESSION['guessedLetters']."\n";
        echo "Letters left: ".$_SESSION['lettersLeft']."\n";
        echo "Game State: ".$_SESSION['gameState']."\n";
        echo "-->\n";
    }

    //print out the keyboard buttons
    public static function PrintKeyboard()
    {
        if (!self::IsLoggedIn())
            return;

        for ($i = 0; $i < strlen(self::$keyboardButtons); $i++)
        {
            $key = substr(self::$keyboardButtons,$i,1);
            $keyAlias = self::ToAlias($key);
            if (stripos($_SESSION['guessedLetters'], $key) === false) //haven't guessed this yet
                echo '<a class="'.$keyAlias.'" href="?m=g&amp;g='.$keyAlias.'"></a>';
            else //we've guessed already
                echo '<span class="'.$keyAlias.'"><img src="games/plank/images/alphabet/'.(stripos($_SESSION['word'], $key) === false?'wrong':'right').'.png" /></span>';
            echo "\n";
        }
    }
}
?>

1 个答案:

答案 0 :(得分:2)

一个常见的错误就是像这样的作业:

$_SESSION = $data;

这将覆盖以前存储的所有信息 更好的做法是使$_SESSION成为具有命名索引的数组:

$_SESSION['somedata'] = $data;

现在,您只会覆盖'somedata'字段中存储的数据。