2012-02-19 88 views
3

情况:似乎不可能将任何对象存储在CI_Session中,因为在加载模型之前,读取它们会导致PHP_Incomplete_Object异常,因为会话始终启动。 这样,即使在自动载入对象类型时,我也无法读取会话中的数据。如何在会话中存储对象(Codeigniter)

我也尝试使用“本机会话”,但它存在完全相同的问题。

此外,我试图存储序列化的对象,但是当加载所有模型后很长的反序列化时,它仍然变成了类型为“__PHP_Incomplete_Class”的对象。

任何人都知道解决方法?请保留“你为什么要在会话中使用对象”的答案。足够的那些...

回答

4

不幸的是,PHP不允许你序列化从另一个对象的引用。这就是为什么当你恢复你的对象时,它不包含它开始的数据。

我提出的最佳解决方案是在我的模型层中创建一个Session对象,该对象使用cookie进行恢复。数据库中的会话表处理对您将要序列化的对象的引用。一旦你的会话模型被加载,你可以使用它来加载'session stored'对象,热切或懒惰地加载。另外,如果这些对象持有对其他模型对象的引用,则可以使用相同的原则根据关系引用遍历模型图层的其余部分。这看起来令人望而生畏,但是如果你不愿意自己实现它,你可以检查一些ORM。

+0

感谢您的意见。但是,将对象存储在会话中应该减少对数据库的查询次数(例如,保存用户的完整ACL)。我现在通过将对象数据转换为一组*有意义的数组并将其写入session-> userdata来解决它。 – DerShodan 2012-02-19 11:33:08

0

我发现另一种选择是,你可以在你的对象存储在session数组值的形式:

你可以将其存储这样的:

$this->session->set_userdata($yourObject); 

访问是这样的:

$this->session->userdata['property name of your object']; 
0

到目前为止我发现的唯一解决方案是让班级成员r与控制器(而不是作为库分开)。

不是很优雅,但由于某种原因,它工作,而CI库实例不会。

所以基本上:

class Main extends CI_Controller { 

    public function index() {   
     $game = new Game(); 
     echo $game->id; 
     $this->session->set_userdata('game',$game); 
    } 

    public function restore_game() {   
     $game = $this->session->userdata('game'); 
     echo $game->id; 
    } 

} 

class Game { 
    public $id; 

    public function __construct() { 
     $this->id = rand(0,100); 
    } 
} 

或者你仍然可以保持类中的“库”文件夹,但采用了经典的require_once而不是$这个 - >负载>库(“游戏”),加载其是会话无法处理的那种对象。

require_once(APPPATH . 'libraries/Game.php'); 

class Main extends CI_Controller { 
    ... 
}