【问题标题】:PHP OOP Session Object - Won't Persist Without Serialize Un-SerializePHP OOP 会话对象 - 不会在没有序列化的情况下持续存在
【发布时间】:2013-01-18 09:04:25
【问题描述】:

我试图弄清楚为什么下面的代码不会跨页面保留我的 $_SESSION['objSession'] 对象,除非我将序列化/反序列化保留在下面。我厌倦了手动序列化/反序列化以在会话中进行对象更改,人们一直说我不应该这样做,但我确实看到其他关于会话对象在没有它的情况下不会在网络上持续存在的抱怨,包括在堆栈上...... PHP 5.3 Apache 2.2 Windows 2008。

<?php require_once("/php/php_clsSession.php");?>
<?php session_start(); ?>
<?php
    // Session Object Create/Log
    $objSession = new clsSession;
    if ( !(isset($_SESSION['objSession']) )) {
        // This line will populate some properties in the obj
        // like Session_ID and Create_dt
        $objSession->CreateSession(session_id(),$_SERVER);
    }
    else {
        // this code will only run if the session is already 
        // set
        $objSession = unserialize($_SESSION['objSession']);
        $objSession->UpdateSession(session_id(),$_SERVER);
    }
    // Update Session Object
    $_SESSION['objSession'] = serialize($objSession);
    unset($objSession);
?>

---- clsSession 在此行下方...您可以忽略 db 包含,因为代码在不使用 db 功能的情况下存在相同的问题,并且无论如何我暂时对 db 函数进行了注释...。

<?php
   // -----------------------------------------------------------------
   // Program Type: Class
   // Program Name: clsSession
   // Program Date: 01/08/2012 Programmer: Tim Wiley
   // Description:  Standard class for session creation/update
   // -----------------------------------------------------------------
  class clsSession {

       // Properties
       public $Session_Id = null;
       public $Creation_Dt = null;
       public $Action_Dt = null;
       public $Session_IP_Address = null;
       public $Browser_Type = null;
       public $Display_Resolution = null;
       public $Is_Https_Ind = null;
       public $Is_Logged_In_Ind = 0;
       public $User_Key = null;
       public $User_Id = null;
       public $Email_Address = null;
       public $Request_Method = null;
       public $Page_Requested = null;
       public $Page_Request_Params = null;
       public $Page_Action = null;
       public $Login_Attempts = 0;
       public $Max_Login_Attempts = 3;

     private function UpdateSessionClassData (&$xSessionId = null, &$xSessionObj = null, &$xPageAction = "N/A" ) {
        $this->Session_Id = &$xSessionId;
        $this->Action_Dt = date( 'Y-m-d H:i:s', time( ));
        $this->Session_IP_Address = substr(trim(&$xSessionObj['REMOTE_ADDR']),0,24);
        $this->Browser_Type = substr(trim(&$xSessionObj['HTTP_USER_AGENT']),0,140);
        $this->Request_Method = substr(trim(&$xSessionObj['REQUEST_METHOD']),0,24);
        $this->Page_Requested = substr(trim(&$xSessionObj['SCRIPT_NAME']),0,140);
        $this->Page_Request_Params = substr(trim(&$xSessionObj['QUERY_STRING']),0,140);
        $this->Is_Https_Ind = &$xSessionObj['SERVER_PORT'] == 443 ? 1 : 0;
        if (is_null($this->Display_Resolution)) {
            require_once('/javascript/js_SaveScreenResolutionInCookie.js');
            $this->Display_Resolution = !( IS_NULL( $_COOKIE['users_resolution'] )) ? substr(trim($_COOKIE['users_resolution']),0,16) : "N/A";
        }
        $this->Page_Action = substr(trim(&$xPageAction),0,32);
     }
     // Initialize Session objSession for $_SESSION
     public function CreateSession($xSessionId = null, &$xSessionObj = null ) {
        $this->Creation_Dt = date( 'Y-m-d H:i:s', time( ));
        $this->UpdateSessionClassData(&$xSessionId, &$xSessionObj);
       // $this->WriteSessionToDb();
        }

     // Update Session objSession for $_SESSION
     public function UpdateSession($xSessionId = null, &$xSessionObj = null, $xPageAction = "N/A" ) {
        $this->UpdateSessionClassData(&$xSessionId, &$xSessionObj, &$xPageAction);
       // $this->WriteSessionActivityToDb();
        }

      // Writes the session data to database
      public function WriteSessionToDb($xUserType = "Web") {
              $objConnect = new clsDb;
              $objDb = $objConnect->GetDbConnection($xUserType);
              //$objDb = $this->GetDbConnection($xUserType);
              $_InsertSQL = new PDOStatement;
              $_InsertSQL = $objDb->prepare("INSERT INTO T_SESSION_STATS(" .
                  "F_ACTION_DT, F_SESSION_ID, F_SESSION_IP_ADDRESS, F_BROWSER_TYPE," .
                  "F_DISPLAY_RESOLUTION, F_PAGE_REQUESTED, F_PAGE_REQUEST_PARAMS," .
                  "F_REQUEST_METHOD, F_IS_HTTPS_IND, F_IS_LOGGED_IN_IND, F_USER_KEY)" .
                  "Values (?,?,?,?,?,?,?,?,?,?,?)");
              $_InsertSQL->bindParam(1, $this->Action_Dt );
              $_InsertSQL->bindParam(2, $this->Session_Id );
              $_InsertSQL->bindParam(3, $this->Session_IP_Address );
              $_InsertSQL->bindParam(4, $this->Browser_Type );
              $_InsertSQL->bindParam(5, $this->Display_Resolution );
              $_InsertSQL->bindParam(6, $this->Page_Requested );
              $_InsertSQL->bindParam(7, $this->Page_Request_Params );
              $_InsertSQL->bindParam(8, $this->Request_Method );
              $_InsertSQL->bindParam(9, $this->Is_Https_Ind );
              $_InsertSQL->bindParam(10, $this->Is_Logged_In_Ind );
              $_InsertSQL->bindParam(11, $this->User_Key );
          try {
            $objDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $objDb->beginTransaction();
            $_InsertSQL->execute();
            $objDb->commit();
            unset($objDb);
          } catch (Exception $e) {
            $objDb->rollBack();
            echo "Failed: " . $e->getMessage();
            unset($objDb);
            unset($objConnect);
          }
      }

        // Writes the session data to database
        public function WriteSessionActivityToDb($xUserType = "Web",$xPageAction = "N/A") {
                $objConnect = new clsDb;
                $objDb = $objConnect->GetDbConnection($xUserType);
                //$objDb = $this->GetDbConnection($xUserType);
                $_InsertSQL = new PDOStatement;
                $_InsertSQL = $objDb->prepare("INSERT INTO T_SESSION_ACTIVITIES(" .
                    "F_ACTION_DT, F_SESSION_ID, F_SESSION_IP_ADDRESS, " .
                    "F_PAGE_REQUESTED, F_PAGE_REQUEST_PARAMS," .
                    "F_REQUEST_METHOD, F_PAGE_ACTION, F_IS_HTTPS_IND, F_IS_LOGGED_IN_IND, F_USER_KEY)" .
                    "Values (?,?,?,?,?,?,?,?,?,?)");
                $_InsertSQL->bindParam(1, $this->Action_Dt );
                $_InsertSQL->bindParam(2, $this->Session_Id );
                $_InsertSQL->bindParam(3, $this->Session_IP_Address );
                $_InsertSQL->bindParam(4, $this->Page_Requested );
                $_InsertSQL->bindParam(5, $this->Page_Request_Params );
                $_InsertSQL->bindParam(6, $this->Request_Method );
                $_InsertSQL->bindParam(7, substr(trim($xPageAction),0,32));
                $_InsertSQL->bindParam(8, $this->Is_Https_Ind );
                $_InsertSQL->bindParam(9, $this->Is_Logged_In_Ind );
                $_InsertSQL->bindParam(10, $this->User_Key );
            try {
              $objDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
              $objDb->beginTransaction();
              $_InsertSQL->execute();
              $objDb->commit();
              unset($objDb);
              unset($objConnect);
            } catch (Exception $e) {
              $objDb->rollBack();
              unset($objDb);
              echo "Failed: " . $e->getMessage();
            }
        }
    }

?>

【问题讨论】:

  • 嘿,删除了另一边的一条虚假线路……只是错字,所以不要认为这是问题所在。
  • 您看到了什么问题?检查时是否没有出现更改或$_SESSION['objSession']为空?
  • thx Jim - isset 在辅助页面请求上测试为真,但最初使用 CreateSession 方法设置的属性值为空。我可以在相同的代码旁边创建另一个简单的 $_SESSION 变量,该代码只是文本/数字,并且它每次都会持续存在。
  • 请也发布您的对象定义。
  • 如果将session_write_close() 放在文件末尾(不使用 un-/serialize)会发生什么?

标签: php


【解决方案1】:

问题似乎出在您的 clsSession 班级中。这是使用&amp;。由于会话对象已序列化,因此这些引用未正确存储。尝试删除这些(即更改 UpdateSessionClassDataUpdateSession 以从参数中删除 &amp;),看看这是否解决了问题。

【讨论】:

  • Jim - thx 伙计...我在数百次迭代中完美地摆脱了引用传递。 - 非常感谢....顺便说一句,如果您对我如何不必更改 tmpobj 属性然后不得不将整个对象重新分配回会话 ['objSession'] 有任何想法,请告诉我我是时候做出改变了。我希望拥有智能感知并能够直接更改对象属性。
  • @TimWiley 如果我记得正确地更新会话中的对象应该可以工作,而无需重新插入会话。
【解决方案2】:

首先,将session_start(); 放在require_once 之前并添加var_dump($_SESSION) 进行调试。

【讨论】:

  • session_start() 放在require 之前不是一个好主意。 PHP序列化进入会话的对象,反序列化时类定义必须存在。
  • 正是我最初有 session_start() 和同样的问题,但我将它移到第二行,因为它必须首先用于会话对象。无论会话本身是否持续存在 objSession 对象,问题是对象中设置的属性没有持续存在。简单的会话变量在相同的代码中工作正常,但仅在分配对象时才会出现问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
相关资源
最近更新 更多