zoukankan      html  css  js  c++  java
  • CodeIgniter的Session问题

    最近有个项目接触到CodeIgniter,让我很是惊叹它的精巧,于是决定用它来做下一个项目。果然,蜜月期过了,毛病就出来了,具体的就是Session的问题。CodeIgniter的Session有两种方式,默认的Session是用Cookie来存储的,也可以切换到数据库存储,但是无论哪种Session都会有些很致命的问题,就是丢失数据。

    比如 Controller a.php

       1: <?php if (! defined('BASEPATH')) exit('No direct script access allowed');
       2:  
       3: class A extends CI_Controller {
       4:     function __construct()
       5:     {
       6:         parent::__construct();
       7:     }
       8:     function index()
       9:     {
      10:         $this->load->view('a');
      11:     }
      12:     function test()
      13:     {
      14:         $user_data=array();
      15:         $user_data['testval']=$this->input->post('testval');
      16:         $this->session->set_userdata($user_data);
      17:         redirect('b','refresh');
      18:     }
      19: }
      20: ?>
      21:         

    Controller B:

       1: <?php if (! defined('BASEPATH')) exit('No direct script access allowed');
       2:  
       3: class B extends CI_Controller {
       4:     fucntion __construct()
       5:     {
       6:         parent::__construct();
       7:     }
       8:     function index()
       9:     {
      10:         echo('#'. $this->session->userdata('testval') . '#');
      11:         $this->load->view('a');
      12:     }
      13: }
      14: ?>

    View A:

       1: <hr/>
       2: <form action="A/test" method="post">
       3: <input type="text" name="testval" id="testval" value="1234" />
       4: <input type="submit" value="submit"/>
       5: </form>

    在autoload.php里面修改,加上对 Session的load

       1: $autoload['libraries']=array('database','session');

    然后访问 A, 比如  http://localhost/A, 点提交之后应该刷新,在刷新后的页面上显示出来 1234, 然后神奇的事情发生了。。。 Session没了, 对于redirect, CodeIgniter自动的创建了一个新的session,同样的道理,如果用Ajax访问,也会有个新的Session被创立,结果导致了这个Session根本不能用!

    折腾了整整一天也没什么效果,后来在github上面找到了一个大牛自己改写的Session Library, 核心就是弃用cookie,转而使用php native session, 保留了一些基本功能,比如 set_userdata(),这需要用下面的代码 覆盖 system/libraries/Session.php 文件

       1: <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
       2: /**
       3:  * Code Igniter
       4:  *
       5:  * An open source application development framework for PHP 4.3.2 or newer
       6:  *
       7:  * @package        CodeIgniter
       8:  * @author        Dariusz Debowczyk
       9:  * @copyright    Copyright (c) 2006, D.Debowczyk
      10:  * @license        http://www.codeignitor.com/user_guide/license.html 
      11:  * @link        http://www.codeigniter.com
      12:  * @since        Version 1.0
      13:  * @filesource
      14:  */
      15:  
      16: // ------------------------------------------------------------------------
      17:  
      18: /**
      19:  * Session class using native PHP session features and hardened against session fixation.
      20:  * 
      21:  * @package        CodeIgniter
      22:  * @subpackage    Libraries
      23:  * @category    Sessions
      24:  * @author        Dariusz Debowczyk
      25:  * @link        http://www.codeigniter.com/user_guide/libraries/sessions.html
      26:  */
      27: //class Native_session {
      28: class CI_Session {
      29:     var $session_id_ttl; // session id time to live (TTL) in seconds
      30:     var $flash_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
      31:     
      32:    // function Native_session()
      33:     function CI_Session()
      34:     {
      35:         $this->object =& get_instance();
      36:         log_message('debug', "Native_session Class Initialized");
      37:         $this->_sess_run();
      38:     }
      39:  
      40:     /**
      41:     * Regenerates session id
      42:     */
      43:     function regenerate_id()
      44:     {
      45:         // copy old session data, including its id
      46:         $old_session_id = session_id();
      47:         $old_session_data = $_SESSION;
      48:  
      49:         // regenerate session id and store it
      50:         session_regenerate_id();
      51:         $new_session_id = session_id();
      52:         
      53:         // switch to the old session and destroy its storage
      54:         session_id($old_session_id);
      55:         session_destroy();
      56:         
      57:         // switch back to the new session id and send the cookie
      58:         session_id($new_session_id);
      59:         session_start();
      60:         
      61:         // restore the old session data into the new session
      62:         $_SESSION = $old_session_data;
      63:         
      64:         // update the session creation time
      65:         $_SESSION['regenerated'] = time();
      66:  
      67:         // session_write_close() patch based on this thread
      68:         // http://www.codeigniter.com/forums/viewthread/1624/
      69:         // there is a question mark ?? as to side affects
      70:  
      71:         // end the current session and store session data.
      72:         session_write_close();
      73:     }
      74:     
      75:     /**
      76:     * Destroys the session and erases session storage
      77:     */
      78:     function destroy()
      79:     {
      80:         unset($_SESSION);
      81:         if ( isset( $_COOKIE[session_name()] ) )
      82:         {
      83:               setcookie(session_name(), '', time()-42000, '/');
      84:         }
      85:         session_destroy();
      86:     }
      87:     
      88:     /**
      89:     * Reads given session attribute value
      90:     */    
      91:     function userdata($item)
      92:     {
      93:         if($item == 'session_id'){ //added for backward-compatibility
      94:             return session_id();
      95:         }else{
      96:             return ( ! isset($_SESSION[$item])) ? false : $_SESSION[$item];
      97:         }
      98:     }
      99:     
     100:     /**
     101:     * Sets session attributes to the given values
     102:     */
     103:     function set_userdata($newdata = array(), $newval = '')
     104:     {
     105:         if (is_string($newdata))
     106:         {
     107:             $newdata = array($newdata => $newval);
     108:         }
     109:     
     110:         if (count($newdata) > 0)
     111:         {
     112:             foreach ($newdata as $key => $val)
     113:             {
     114:                 $_SESSION[$key] = $val;
     115:             }
     116:         }
     117:     }
     118:     
     119:     /**
     120:     * Erases given session attributes
     121:     */
     122:     function unset_userdata($newdata = array())
     123:     {
     124:         if (is_string($newdata))
     125:         {
     126:             $newdata = array($newdata => '');
     127:         }
     128:     
     129:         if (count($newdata) > 0)
     130:         {
     131:             foreach ($newdata as $key => $val)
     132:             {
     133:                 unset($_SESSION[$key]);
     134:             }
     135:         }        
     136:     }
     137:     
     138:     /**
     139:     * Starts up the session system for current request
     140:     */
     141:     function _sess_run()
     142:     {
     143:         $session_id_ttl = $this->object->config->item('sess_expiration');
     144:         
     145:         if (is_numeric($session_id_ttl))
     146:         {
     147:             if ($session_id_ttl > 0)
     148:             {
     149:                 $this->session_id_ttl = $this->object->config->item('sess_expiration');
     150:             }
     151:             else
     152:             {
     153:                 $this->session_id_ttl = (60*60*24*365*2);
     154:             }
     155:         }
     156:         session_start();
     157:         
     158:         // check if session id needs regeneration
     159:         if ( $this->_session_id_expired() )
     160:         {
     161:             // regenerate session id (session data stays the
     162:             // same, but old session storage is destroyed)
     163:             $this->regenerate_id();
     164:         }
     165:         
     166:         // delete old flashdata (from last request)
     167:         $this->_flashdata_sweep();
     168:         
     169:         // mark all new flashdata as old (data will be deleted before next request)
     170:         $this->_flashdata_mark();
     171:     }
     172:     
     173:     /**
     174:     * Checks if session has expired
     175:     */
     176:     function _session_id_expired()
     177:     {
     178:         if ( !isset( $_SESSION['regenerated'] ) )
     179:         {
     180:             $_SESSION['regenerated'] = time();
     181:             return false;
     182:         }
     183:         
     184:         $expiry_time = time() - $this->session_id_ttl;
     185:         
     186:         if ( $_SESSION['regenerated'] <=  $expiry_time )
     187:         {
     188:             return true;
     189:         }
     190:  
     191:         return false;
     192:     }
     193:     
     194:     /**
     195:     * Sets "flash" data which will be available only in next request (then it will
     196:     * be deleted from session). You can use it to implement "Save succeeded" messages
     197:     * after redirect.
     198:     */
     199:     function set_flashdata($key, $value)
     200:     {
     201:         $flash_key = $this->flash_key.':new:'.$key;
     202:         $this->set_userdata($flash_key, $value);
     203:     }
     204:     
     205:     /**
     206:     * Keeps existing "flash" data available to next request.
     207:     */
     208:     function keep_flashdata($key)
     209:     {
     210:         $old_flash_key = $this->flash_key.':old:'.$key;
     211:         $value = $this->userdata($old_flash_key);
     212:  
     213:         $new_flash_key = $this->flash_key.':new:'.$key;
     214:         $this->set_userdata($new_flash_key, $value);
     215:     }
     216:  
     217:     /**
     218:     * Returns "flash" data for the given key.
     219:     */
     220:     function flashdata($key)
     221:     {
     222:         $flash_key = $this->flash_key.':old:'.$key;
     223:         return $this->userdata($flash_key);
     224:     }
     225:     
     226:     /**
     227:     * PRIVATE: Internal method - marks "flash" session attributes as 'old'
     228:     */
     229:     function _flashdata_mark()
     230:     {
     231:         foreach ($_SESSION as $name => $value)
     232:         {
     233:             $parts = explode(':new:', $name);
     234:             if (is_array($parts) && count($parts) == 2)
     235:             {
     236:                 $new_name = $this->flash_key.':old:'.$parts[1];
     237:                 $this->set_userdata($new_name, $value);
     238:                 $this->unset_userdata($name);
     239:             }
     240:         }
     241:     }
     242:  
     243:     /**
     244:     * PRIVATE: Internal method - removes "flash" session marked as 'old'
     245:     */
     246:     function _flashdata_sweep()
     247:     {
     248:         foreach ($_SESSION as $name => $value)
     249:         {
     250:             $parts = explode(':old:', $name);
     251:             if (is_array($parts) && count($parts) == 2 && $parts[0] == $this->flash_key)
     252:             {
     253:                 $this->unset_userdata($name);
     254:             }
     255:         }
     256:     }
     257: }
     258: ?>

    问题解决了,但是也有局限,

    第一 $this->session->sess_create() 和$this->session->sess_destroy() 不见了, 这倒无所谓,没太大影响, 可以用 $this->session->destroy(),

    第二,这修改了CodeIgniter的system library,并不是特别好的解决方法。。。

    哎~ 不过不管怎么说,解决了, 浪费了整整1天的时间。。。

    点击这里下载Session.php ,修改自 https://github.com/EllisLab/CodeIgniter/wiki/Native-session

  • 相关阅读:
    mingw 构建 Geos
    nmake构建Geos库
    使用Dlib来运行基于CNN的人脸检测
    DLib Http Server程序示例
    DLib压缩解压程序示例
    GDAL添加ECW格式支持
    Dlib机器学习指南图翻译
    DLib库Base64编解码示例
    Dlib三维点云示例
    Mingw编译DLib
  • 原文地址:https://www.cnblogs.com/lei1016cn/p/2719028.html
Copyright © 2011-2022 走看看