我有一个PHP脚本,它通过Dojo Ajax xhrGet调用以两种方式调用。 第一次使用“init”参数调用它会导致脚本创建StateList类的实例并读入状态名称的文件。
session_start();
@include('StateList.php');
require_once('phplog.php');
//start executing here
$comd=$_GET['nexturl'];
if($comd=="init") {
$st = new StateList("../data/statestxt.txt");
$_SESSION['statefile'] = $st;
}
第二次和另外一次,另一个xhrGet调用传递一个“getstate”参数,下面的代码试图从SESSION数组中获取StateList类的实例。
if($comd =="getstate") {
$st= $_SESSION['statefile'];
phplog("size=".$st->getSize());
}
但是,从不执行getSize()方法,也不能调用任何其他方法 在重构的StateList类实例上。
请注意,这是一个PHP脚本,它包含顶部的类定义 因此,类方法应该是已知的和可用的。
我在这里缺少什么?
答案 0 :(得分:13)
您需要在调用session_start()
之前包含类定义,否则该对象将不会被正确反序列化,并且将成为__PHP_Incomplete_Class
的实例。否则你所拥有的应该可以正常工作。
答案 1 :(得分:1)
在存储之前,您可能需要serialize $ st对象/变量。这将确保将所有内容保存到会话中。这绝对是object oriented代码的方法。如果要再次使用数据,则必须unserialize。
答案 2 :(得分:1)
这是难以独立调试的事情之一。在PHP会话中存储实例化对象总是有点棘手,并且不能100%保证可以正常工作。以下是一些常见的调试技巧,可以帮助您解决这个问题。
首先,检查您的apache错误日志。你得到一个“非对象错误调用方法”吗?如果是这样,这意味着您没有从会话中恢复对象。如果没有,是否有错误表明您的方法调用由于其他原因而失败?
其次,检查一下你的会话实际上是什么。
if($comd =="getstate") {
$st= $_SESSION['statefile'];
//get the class of st
phplog("instance=".get_class($st));
//get a reflection dump of st
$ref = new ReflectionClass($st);
$string = $ref->__toString();
phplog("reflection=".$string);
}
第三,查看会话本身存储的序列化字符串值。你实际上存储一个序列化的对象?在你的开发环境中,将php.ini中的session.save_path ini值设置为/ tmp,(或使用ini_set方法执行相同的操作):
session.save_path = "/tmp"
然后检查在/ tmp(或任何文件夹)中创建的文件。您应该看到一个以:
开头的字符串statefile:O:..........
实例化对象的类的名称也将包含在那里,以及保存到属性的值。
答案 3 :(得分:0)
如果要在会话中存储一个对象,它必须是link text。在PHP中序列化对象有很多问题,更不用说将它们存储在会话中了。我建议不要这样做,并为您的问题找到不同的解决方案。如果您打算这样做,您应该查看您应该在类中定义的“魔术方法”link text,以便在从会话中调用它时进行重新实现。
答案 4 :(得分:0)
您是否启用了session.auto_start
?手册的会话页面指出,如果这样做,则必须以不同方式加载类定义:
如果打开session.auto_start,那么将对象放入会话的唯一方法是使用auto_prepend_file加载其类定义,在其中加载类定义,否则必须序列化对象并在之后对其进行反序列化。
http://php.net/manual/en/intro.session.php
正如该页面所说,对象的序列化/反序列化通常由PHP自动完成,但启用session.auto_start
会改变它。
答案 5 :(得分:0)
试试这个:
include('StateList.php');
require_once('phplog.php');
// start your session after including your class file
session_start();
//start executing here
$comd=$_GET['nexturl'];
if($comd=="init") {
$st = new StateList("../data/statestxt.txt");
$_SESSION['statefile'] = $st;
}
if($comd =="getstate") {
// the ampersand creates a reference, preserving any further changes to your session data
$st = &$_SESSION['statefile'];
phplog("size=".$st->getSize());
}