带有不完整对象的PHP会话

时间:2009-06-28 20:48:33

标签: php session object

我收到错误我不知道如何解决,所以我想知道我是否能得到一些帮助。

这是错误

Fatal error: process_form() [<a href='function.process-form'>function.process-form</a>]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition &quot;Template&quot; of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in /home/twinmeddev/html/template_add.php on line 44

我在process_form()函数中遇到此错误。所以我从中得到的是,它认为我没有为模板加载类。事实上,我在顶部做了什么。包含'inc / item.class.php';我是否必须将其重新包含在功能中?

以下是包含错误的特定页面的代码。你可以看到我拥有应有的一切。我哪里出错?

<?php
include 'inc/prep.php';
include 'inc/header.class.php';
include 'inc/item.class.php';
include 'inc/template.class.php';
include 'inc/formhelper.class.php';
include 'inc/formvalidator.class.php';
include_once( 'inc/config/config.php' ) ;
include_once( 'inc/DBE.class.php' ) ;
include_once( 'inc/GenFuncs.php' ) ;
include_once( 'inc/Search.class.php' ) ;

session_start();    

//Verify that user is logged in.
VerifyLogin($_SERVER['PHP_SELF'] . "?" . $_SERVER['QUERY_STRING']);

if(array_key_exists('_submit',$_POST)) {
    if($fv_errors = validate_form()) {
        show_form($fv_errors);
    } else {
        process_form();
    }
}
else {
    // The form wasn't submitted or preview was selected, so display
    show_form();
}

function validate_form(){
}

function process_form(){
    global $mysqli;

    echo var_dump($_SESSION);

    $Template = $_SESSION['template'];
    $Template->name = $_POST['name'];
    $Template->descript = $_POST['descript'];
    $Template->user = $_SESSION['User'];
    $Template->customer = $_SESSION['CustID'];
    $Template->status = $_POST['status'];
    $Template->insert();

    //header("Location: template.php");
}

7 个答案:

答案 0 :(得分:66)

它缺少模板类的序列化/反序列化。

在这里查看working example我给你的另一个问题。

例如,你可能想要这个:

<?php
  $_SESSION['template'] = serialize($template);
?>

<?php
  $template = unserialize($_SESSION['template']);
?>

编辑:

阅读关于将其移至顶部的评论会给出一个提示。

当您致电session_start()时,会发生自动序列化/反序列化 这意味着您包含文件并调用session_start()的顺序非常重要。

例如:

这是错误的:

<?php
session_start();
include 'inc/template.class.php';
?>

虽然这是正确的:

<?php
include 'inc/template.class.php';
session_start();
?>

现在,我在你的例子中看到它是在CORRECT顺序中,但我也注意到在包括template.class.php之前你还做了很多其他的包含

其中一个包括(也许是prep.php或header.class.php)是否也可以调用start_session()? 如果是,那就是你的问题(在你的template.class.php之前调用session_start())。

答案 1 :(得分:9)

当您在session_start()数组$_SESSION中填充相应的对象时。这意味着所有接口必须可用(需要)。如果会话已经由另一个在接口上没有可见性的脚本(例如框架)启动,$ _SESSION中的对象将不完整,再次执行session_start()是没用的,因为会话已经已经开始了。一种可能的解决方案是使用方法session_write_close(),然后session_start()再次开始填充$_SESSION,但是可以看到界面,因此$_SESSION中的对象会很好。< / p>

答案 2 :(得分:5)

我已在similar question上发布了我的答案,再次发布,因为它也回答了这个问题。

PHP使用内置的serializeunserialize方法序列化其会话。 PHP的serialize能够序列化PHP对象(也称为类实例)并将它们转换为字符串。当你unserialize这些字符串时,它会将这些字符串转换回那些相同的类。具有某些私有属性并希望对其进行编码/解码或在序列化/反序列化中执行复杂操作的类实现Serializable类并向该类添加serializeunserialize方法。

当PHP的unserialize尝试反序列化一个类对象,但没有声明/要求类名时,它不会发出警告或抛出Exception,而是将其转换为{的对象{1}}。

如果您不希望会话对象转换为__PHP_Incomplete_Class,您可以通过在调用session_start之前要求类文件,或者通过注册自动加载功能来执行此操作。

答案 3 :(得分:2)

您在会话中放置的对象有多大?当我的对象大于我们在php.ini文件中为会话分配的空间时,我得到了类似的错误。如果对象太大,那么当它不应该是空的时候会回来。

之后,我刚刚开始在Session中存储对象的PK,如果我需要它而不是随身携带整个对象,那就查找它。

您还可以在INI文件中增加会话的大小,看看是否会产生影响。

答案 4 :(得分:2)

请确保您尝试操作的对象的类定义“模板”已在之前加载 ...
我猜include 'inc/template.class.php';应该加载类模板的定义?
那么也许包括失败了。请改为require
<?php
require 'inc/prep.php';
require 'inc/header.class.php';
require 'inc/item.class.php';
require 'inc/template.class.php';
require 'inc/formhelper.class.php';
require 'inc/formvalidator.class.php';
require_once( 'inc/config/config.php' ) ;
require_once( 'inc/DBE.class.php' ) ;
require_once( 'inc/GenFuncs.php' ) ;
require_once( 'inc/Search.class.php' ) ;

if ( !class_exists('Template') ) { die('No. Those include/requires did not define the class "Template"'); } session_start();

答案 5 :(得分:1)

我也尝试将对象存储在会话变量中。是的,我遇到了与MackDaddy相同的问题。并通过将类的包含移动到第一个来解决。

所以..

require_once("class.someclass.php");
require_once("display.php");

工作

但不是......

require_once("display.php");
require_once("class.someclass.php");
嗯...不知道理性是什么?如果我们有2个或更多不同的对象怎么办?哪一个先来?

答案 6 :(得分:0)

在我的情况下,正如Carlos在回答中提到的那样,我在其中包含我的文件并且调用session_start()的顺序是不正确的。

但我无法修理订单。

这个解决方法对我有用:

$_SESSION["template"] = unserialize(serialize($_SESSION["template"]))