情况:似乎不可能在CI_Session中存储任何对象,因为读取它们会导致PHP_Incomplete_Object异常,因为会话总是在加载模型之前启动的。这样,即使在自动加载对象类型时,我也永远无法从会话中读取数据。
我也尝试过使用"Native Session",但问题完全一样。
此外,我尝试存储序列化的对象,但当在加载所有模型后很长一段时间才取消序列化时,它仍然会变成一个类型为"__PHP_Incomplete_Class"的对象。
有人知道变通办法吗?请保留"你为什么要在会话中使用对象"的答案。看够了这些。。。
不幸的是,php不允许您从另一个对象序列化对一个对象的引用。这就是为什么当您恢复对象时,它不包含它开始时使用的数据。
我想出的最好的解决方案是在我的模型层中创建一个会话对象,该对象使用cookie进行恢复。数据库中的会话表处理对对象的引用,否则这些对象将被序列化。一旦您的会话模型被加载,您就可以使用它来加载"会话存储"对象,无论是急切地还是懒散地。
此外,如果这些对象包含对其他模型对象的引用,则可以使用相同的原理,基于关系引用遍历模型层的其余部分。这看起来可能令人望而生畏,但如果您觉得自己不太愿意实现它,您可以查看许多ORM。
我发现的另一个选项是,您可以以会话数组值的形式存储对象:
您可以这样存储:
$this->session->set_userdata($yourObject);
访问方式如下:
$this->session->userdata['property name of your object'];
到目前为止,我找到的唯一解决方案是将类与控制器放在一起(而不是作为库分离)。
不是很经典,但由于某些原因,它可以工作,而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);
}
}
或者,您仍然可以将类保存在"libraries"文件夹中,但使用经典的require_once加载它,而不是$this->load->library("Game"),后者是会话无法处理的对象。
require_once(APPPATH . 'libraries/Game.php');
class Main extends CI_Controller {
...
}