Сессия PHP с неполным объектом

Я получаю ошибку, я не знаю, как это исправить, поэтому мне интересно, смогу ли я получить какую-то помощь.

Это ошибка

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"); } 

Отсутствует сериализация / unserialize вашего шаблона.

Взгляните сюда на рабочий пример, который я дал на ваш другой вопрос.

Например, вы, вероятно, захотите этого:

 <?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() ?
Если да, это была ваша проблема ( session_start() вызывается до вашего template.class.php).

Когда session_start() в $_SESSION php $_SESSION заполняется соответствующими объектами. Это означает, что все интерфейсы должны быть доступны (требуется). Если сеанс уже был запущен ранее другим сценарием (например, каркасом), который не имел видимости на интерфейсах, объекты в $ _SESSION будут неполными, а делать это снова session_start() бесполезно, поскольку сеанс уже запущен. Одним из возможных решений является использование метода session_write_close() , а затем session_start() который начинает снова заполнять $_SESSION , но с видимостью в интерфейсе, поэтому ваш объект в $_SESSION будет хорошим.

Я отправил свой ответ по аналогичному вопросу , разместив его снова, потому что он тоже отвечает на этот вопрос.

PHP выполняет сериализацию своих сессий с использованием встроенных методов serialize и unserialize . serialize PHP имеет возможность сериализовать объекты PHP (аналогично экземплярам класса) и преобразовать их в строку. Когда вы unserialize эти строки, он преобразует их обратно теми же классами с этими значениями. Классы, которые имеют некоторые частные свойства и хотят кодировать / декодировать или выполнять что-то сложное в своей сериализации / десериализации, реализуют класс Serializable и добавляют к классу методы serialize и unserialize .

Когда unserialize PHP пытается не инициализировать объект класса, но имя класса не объявлено / не требуется, вместо того, чтобы давать предупреждение или бросать Exception , оно преобразует его в объект __PHP_Incomplete_Class .

Если вы не хотите, чтобы ваши объекты сеанса конвертировались в __PHP_Incomplete_Class , вы можете сделать это, либо потребовав файлы класса перед вызовом session_start , либо зарегистрировав функцию автозагрузки.

Насколько велики объекты, которые вы вкладываете в сеанс? Я получил аналогичную ошибку, когда мои объекты были больше, чем пространство, которое мы выделили для сеанса в файле php.ini. Если объект был слишком велик, он возвращался бы как пустой, если бы этого не было.

После этого я только начал записывать PK объекта в сеанс и искать его, если мне это нужно, вместо того, чтобы переносить весь объект.

Вы также можете увеличить размер сеанса в файле INI и посмотреть, не изменилось ли это.

Убедитесь, что класс « Шаблон » объекта, который вы пытаетесь использовать, был загружен до

Я предполагаю, что include 'inc/template.class.php'; Предполагается загрузить определение шаблона класса?
Тогда возможно включение не удалась. Попробуйте вместо этого попросить.

 <?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' ) ; 

<?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 («Нет. Те, которые включают / требуют, не определяют класс« Шаблон »);
}
session_start ();

Я также пытался хранить объекты в переменной сеанса. и да, я испытал ту же проблему, что и MackDaddy. и его решить, перенеся включение класса в первое.

так..

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

работал

но нет…

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

хм … интересно, что рационально? и что, если у нас есть два или более разных объекта? который первый?

В моем случае заказ, в который я включал свои файлы и называемый session_start() был неверным, как упоминал Карлос в своем ответе.

Но я не мог исправить порядок.

Этот обходной путь работал на меня:

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