Вопрос по php, object, session – Сессия PHP с незавершенным объектом

35

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

Это ошибка

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");
}
Каковы ваши настройки файла php.ini для session.auto_start? Tom Haigh

Ваш Ответ

7   ответов
0

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

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

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

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

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

Brilliant. Это решило проблему с использованием моего собственного класса корзины покупок (который использует $ _SESSION в качестве контейнера для корзины) в сочетании с Wordpress (который уже начал сеанс). Спасибо!
66

В нем отсутствует сериализация / десериализация класса вашего шаблона.

Посмотрите здесь длярабочий пример Я дал еще один твой вопрос.

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

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

а также

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

Edit:

чтение вашего комментария о перемещении его наверх дает одну подсказку.

Автоматическая сериализация / десериализация происходит при вызовеsession_start().
Это означает порядок, в котором вы включаете свои файлы и вызываетеsession_start() очень важно.

Например:

Это было бы неправильно:

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

Пока это будет правильно

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

Теперь я вижу в вашем примере, что это в ПРАВИЛЬНОМ порядке, но я также заметил, что вы делаете много других включений, прежде чем включать template.class.php

Возможно ли, что один из них включает (возможно, prep.php или header.class.php) вызовstart_session() тоже?
Если да, то это была ваша проблема (session_start() вызывается перед вашим template.class.php).

Взяв пример, который я дал вам в другом посте и удалив сериализацию / десериализацию, вы получите следующее: Unserialized $ template: object (__ PHP_Incomplete_Class) # 1 (3) {...}
@MackDaddy: в смысле внесения вклада в сообщество вы должны вернуться к своим вопросам, чтобы дать соответствующие отзывы, а также пометить «принятый ответ». Если ни один ответ не был тем, что вы искали, вы можете добавить свой собственный ответ с тем, что решило вашу проблему.
Ударил его прямо в ноготь, один из классов вызывал session_start (). Спасибо за вашу помощь и проработали это со мной. Ты жжешь! MackDaddy
Насколько я понимаю, PHP автоматически сериализует объект, если вы добавляете его в сеанс, а затем десериализуете его, если вам нужно было присвоить его переменной. По крайней мере, это то, что я прочитал здесь:devshed.com/c/a/PHP/…  Все, что касалось моего объекта, работало хорошо, кроме этого. MackDaddy
Не верьте мне на слово, попробуйте код, который я дал вам в качестве примера, затем попробуйте добавить un / serialize к вашему коду и посмотрите, работает ли он :)
2

Please ensure that the class definition "Template" of the object you are trying to operate on was loaded before...
Похожеinclude 'inc/template.class.php'; предполагается загрузить определение класса Template?
Тогда, возможно, включить не удалось. Пытаться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();

require а такжеinclude идентичны во всех отношениях, за исключением того, как они обрабатывают неудачу. Они оба выдают предупреждение, ноrequire приводит к фатальной ошибке.
5

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

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

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

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

2

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

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

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

1

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

так..

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

работал

но нет...

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

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

Похожие вопросы