Я получаю ошибку, я не знаю, как это исправить, поэтому мне интересно, смогу ли я получить какую-то помощь.
Это ошибка
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 "Template" 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"]))