Сессия 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 "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");
}
Ответы
Ответ 1
Отсутствует сериализация /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).
Ответ 2
Когда массив session_start()
в php $_SESSION
заполняется соответствующими объектами. Это означает, что все интерфейсы должны быть доступны (требуется). Если сеанс уже был запущен ранее с помощью script (например, framework), который не имел видимости на интерфейсах, объекты в $ _SESSION
будут неполными, а сделать это снова session_start()
бесполезно, поскольку сеанс уже запущен, Одно из возможных решений заключается в использовании метода session_write_close()
, затем session_start()
, который начинает снова заполнять $_SESSION
, но с видимостью в интерфейсе, поэтому ваш объект в $_SESSION
будет хорошим.
Ответ 3
Я отправил свой ответ на аналогичный вопрос, разместив его снова, потому что он также отвечает на этот вопрос.
PHP сериализует свои сеансы с помощью встроенного serialize
и unserialize
. serialize
PHP имеет возможность сериализовать объекты PHP (например, экземпляры класса) и преобразовать их в строку. Когда вы unserialize
эти строки, он преобразует их обратно теми же классами с этими значениями. Классы, которые имеют некоторые частные свойства и хотят кодировать/декодировать или выполнять что-то сложное в своей сериализации/десериализации, реализуют класс Serializable
и добавляют serialize
и unserialize
методы для класс.
Когда PHP unserialize
пытается не инициализировать объект класса, но имя класса не объявлено/требуется, вместо того чтобы давать предупреждая или бросая Exception
, он преобразует его в объект __PHP_Incomplete_Class
.
Если вы не хотите, чтобы ваши объекты сеанса конвертировались в __PHP_Incomplete_Class
, вы можете сделать это, либо потребовав файлы класса, прежде чем вы вызовете session_start
, или зарегистрировав функцию автозагрузки.
Ответ 4
Насколько велики объекты, которые вы вкладываете в сеанс? Я получил аналогичную ошибку, когда мои объекты были больше, чем пространство, которое мы выделили для сеанса в файле php.ini. Если объект был слишком большим, он возвращался бы как пустой, если бы он не был.
После этого я просто начал хранить объект PK в сеансе и просматривал его, если мне это нужно, вместо того, чтобы переносить весь объект.
Вы также можете увеличить размер сеанса в INI файле и посмотреть, не изменилось ли это.
Ответ 5
Убедитесь, что определение класса " Шаблон" объекта, с которым вы пытаетесь работать, загрузилось до...
Предполагаю, что 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();
Ответ 6
Я тоже пытался хранить объекты в переменной сеанса. и да, я испытал ту же проблему, что и MackDaddy. и его решить, переместив включение класса в первый.
так..
require_once("class.someclass.php");
require_once("display.php");
работал
но не...
require_once("display.php");
require_once("class.someclass.php");
Хмм... интересно, что рационально? и что, если у нас есть два или более разных объекта? какой из них первый?
Ответ 7
В моем случае заказ, в который я включил свои файлы и назвал session_start()
, был неправильным, как сказал Карлос в своем ответе.
Но я не мог исправить порядок.
Этот обходной путь работал у меня:
$_SESSION["template"] = unserialize(serialize($_SESSION["template"]))