最近有个项目接触到CodeIgniter,让我很是惊叹它的精巧,于是决定用它来做下一个项目。果然,蜜月期过了,毛病就出来了,具体的就是Session的问题。CodeIgniter的Session有两种方式,默认的Session是用Cookie来存储的,也可以切换到数据库存储,但是无论哪种Session都会有些很致命的问题,就是丢失数据。
比如 Controller a.php
'No direct script access allowed');
2:
extends CI_Controller {
function __construct()
5: {
parent::__construct();
7: }
function index()
9: {
'a');
11: }
function test()
13: {
array();
'testval');
16: $this->session->set_userdata($user_data);
'refresh');
18: }
19: }
20: ?>
21:
Controller B:
'No direct script access allowed');
2:
extends CI_Controller {
4: fucntion __construct()
5: {
parent::__construct();
7: }
function index()
9: {
'#');
'a');
12: }
13: }
14: ?>
View A:
/>
>
/>
/>
>
在autoload.php里面修改,加上对 Session的load
'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 文件
'No direct script access allowed');
/**
* Code Igniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author Dariusz Debowczyk
* @copyright Copyright (c) 2006, D.Debowczyk
* @license http://www.codeignitor.com/user_guide/license.html
* @link http://www.codeigniter.com
* @since Version 1.0
* @filesource
*/
15:
// ------------------------------------------------------------------------
17:
/**
* Session class using native PHP session features and hardened against session fixation.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Sessions
* @author Dariusz Debowczyk
* @link http://www.codeigniter.com/user_guide/libraries/sessions.html
*/
//class Native_session {
class CI_Session {
// session id time to live (TTL) in seconds
31:
// function Native_session()
function CI_Session()
34: {
object =& get_instance();
);
37: $this->_sess_run();
38: }
39:
/**
* Regenerates session id
*/
function regenerate_id()
44: {
// copy old session data, including its id
46: $old_session_id = session_id();
47: $old_session_data = $_SESSION;
48:
// regenerate session id and store it
50: session_regenerate_id();
51: $new_session_id = session_id();
52:
// switch to the old session and destroy its storage
54: session_id($old_session_id);
55: session_destroy();
56:
// switch back to the new session id and send the cookie
58: session_id($new_session_id);
59: session_start();
60:
// restore the old session data into the new session
62: $_SESSION = $old_session_data;
63:
// update the session creation time
'regenerated'] = time();
66:
// session_write_close() patch based on this thread
// http://www.codeigniter.com/forums/viewthread/1624/
// there is a question mark ?? as to side affects
70:
// end the current session and store session data.
72: session_write_close();
73: }
74:
/**
* Destroys the session and erases session storage
*/
function destroy()
79: {
unset($_SESSION);
isset( $_COOKIE[session_name()] ) )
82: {
'/');
84: }
85: session_destroy();
86: }
87:
/**
* Reads given session attribute value
*/
function userdata($item)
92: {
//added for backward-compatibility
return session_id();
else{
false : $_SESSION[$item];
97: }
98: }
99:
/**
* Sets session attributes to the given values
*/
'')
104: {
if (is_string($newdata))
106: {
array($newdata => $newval);
108: }
109:
if (count($newdata) > 0)
111: {
as $key => $val)
113: {
114: $_SESSION[$key] = $val;
115: }
116: }
117: }
118:
/**
* Erases given session attributes
*/
array())
123: {
if (is_string($newdata))
125: {
'');
127: }
128:
if (count($newdata) > 0)
130: {
as $key => $val)
132: {
unset($_SESSION[$key]);
134: }
135: }
136: }
137:
/**
* Starts up the session system for current request
*/
function _sess_run()
142: {
'sess_expiration');
144:
if (is_numeric($session_id_ttl))
146: {
if ($session_id_ttl > 0)
148: {
'sess_expiration');
150: }
else
152: {
153: $this->session_id_ttl = (60*60*24*365*2);
154: }
155: }
156: session_start();
157:
// check if session id needs regeneration
if ( $this->_session_id_expired() )
160: {
// regenerate session id (session data stays the
// same, but old session storage is destroyed)
163: $this->regenerate_id();
164: }
165:
// delete old flashdata (from last request)
167: $this->_flashdata_sweep();
168:
// mark all new flashdata as old (data will be deleted before next request)
170: $this->_flashdata_mark();
171: }
172:
/**
* Checks if session has expired
*/
function _session_id_expired()
177: {
'regenerated'] ) )
179: {
'regenerated'] = time();
false;
182: }
183:
184: $expiry_time = time() - $this->session_id_ttl;
185:
'regenerated'] <= $expiry_time )
187: {
true;
189: }
190:
false;
192: }
193:
/**
* after redirect.
*/
function set_flashdata($key, $value)
200: {
':new:'.$key;
202: $this->set_userdata($flash_key, $value);
203: }
204:
/**
*/
function keep_flashdata($key)
209: {
':old:'.$key;
211: $value = $this->userdata($old_flash_key);
212:
':new:'.$key;
214: $this->set_userdata($new_flash_key, $value);
215: }
216:
/**
*/
function flashdata($key)
221: {
':old:'.$key;
return $this->userdata($flash_key);
224: }
225:
/**
*/
function _flashdata_mark()
230: {
as $name => $value)
232: {
':new:', $name);
if (is_array($parts) && count($parts) == 2)
235: {
':old:'.$parts[1];
237: $this->set_userdata($new_name, $value);
238: $this->unset_userdata($name);
239: }
240: }
241: }
242:
/**
*/
function _flashdata_sweep()
247: {
as $name => $value)
249: {
':old:', $name);
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