wake-up-neo.com

PHP Sitzung mit einem unvollständigen Objekt

Ich erhalte eine Fehlermeldung. Ich weiß nicht, wie ich sie reparieren soll. Ich frage mich, ob ich Hilfe bekommen könnte.

Das ist der Fehler

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

Ich erhalte diesen Fehler in der Funktion process_form (). Was ich daraus bekomme, ist das, ich denke, ich habe die Klasse nicht für die Vorlage geladen. Was ich in der Tat ganz oben geschafft habe. Das Include 'inc/item.class.php'; Muss ich es wieder in die Funktion aufnehmen? 

Hier ist der Code für die bestimmte Seite mit dem Fehler. Sie sehen, ich habe alles dabei, wie es sein sollte. Wo bin ich falsch gegangen?

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

Es fehlt das serialize/unserialize Ihrer Template-Klasse.

Schauen Sie hier nach einem Arbeitsbeispiel , das ich zu einer anderen Frage von Ihnen gab.

Zum Beispiel möchten Sie wahrscheinlich Folgendes:

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

und

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

Bearbeiten:

wenn Sie Ihren Kommentar zum Verschieben nach oben lesen, erhalten Sie einen Hinweis.

Die automatische Serialisierung/das Deaktivieren erfolgt, wenn Sie session_start() aufrufen.
Das heißt, die Reihenfolge, in der Sie Ihre Dateien einschließen und die session_start() aufrufen, ist sehr wichtig.

Zum Beispiel:

Das wäre falsch:

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

Dies wäre zwar richtig:

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

Ich sehe in Ihrem Beispiel, dass es in der richtigen Reihenfolge ist, aber ich stelle auch fest, dass Sie viele andere Include-Vorgänge ausführen, bevor Sie template.class.php einfügen 

Wäre es möglich, dass eines dieser Includes (vielleicht prep.php oder header.class.php) auch start_session() aufruft?
Wenn ja, war dies Ihr Problem (session_start(), das vor Ihrer template.class.php aufgerufen wurde).

66
Carlos Lima

Wenn Sie session_start() in php $_SESSION das Array mit den entsprechenden Objekten gefüllt haben. Dies bedeutet, dass alle Schnittstellen verfügbar sein müssen (erfordern). Wenn die Sitzung bereits zuvor von einem anderen Skript (z. B. Framework) ohne Sichtbarkeit der Schnittstellen gestartet wurde, sind Objekte in $ _SESSION unvollständig und wiederholen es. session_start() ist unbrauchbar, da die Sitzung bereits gestartet wurde. Eine mögliche Lösung ist die Verwendung der Methode session_write_close(), dann session_start(), die erneut mit $_SESSION aufgefüllt wird, jedoch mit Sichtbarkeit der Schnittstelle, so dass Ihr Objekt in $_SESSION gut ist.

9
Vinx

Ich habe meine Antwort in einer ähnlichen Frage gepostet und erneut gepostet, weil sie auch diese beantwortet.

PHP serialisiert seine Sitzungen mit den integrierten Methoden serialize und unserialize . serialize von PHP kann PHP -Objekte (auch als Klasseninstanzen bezeichnet) serialisieren und in einen String konvertieren. Wenn Sie unserialize diese Zeichenfolgen konvertieren, werden dieselben Klassen mit diesen Werten zurückkonvertiert. Klassen, die über einige private Eigenschaften verfügen und dies in ihrer Serialisierung/Deserialisierung verschlüsseln/dekodieren oder etwas komplexes tun möchten, implementieren die Klasse Serializable class und fügen der Klasse die serialize und unserialize - Methoden hinzu.

Wenn PHP unserialize versucht, ein Klassenobjekt zu desialisieren, der Klassenname jedoch nicht deklariert/erforderlich ist, wird keine Warnung ausgegeben oder eine Exception ausgegeben, sondern in ein Objekt von __PHP_Incomplete_Class konvertiert.

Wenn Sie nicht möchten, dass Ihre Sitzungsobjekte in __PHP_Incomplete_Class konvertiert werden, können Sie dies tun, indem Sie entweder die Klassendateien anfordern, bevor Sie session_start aufrufen, oder indem Sie eine Autoload-Funktion registrieren.

5
Steel Brain

Wie groß sind die Objekte, die Sie in die Sitzung einfügen? Ich habe einmal einen ähnlichen Fehler erhalten, als meine Objekte größer waren als der Platz, den wir für die Sitzung in der Datei php.ini zugewiesen hatten. Wenn das Objekt zu groß ist, würde es als leer zurückkehren, wenn es nicht hätte sein sollen.

Danach habe ich gerade begonnen, den PK des Objekts in der Sitzung zu speichern und nachzuschauen, ob ich es brauchte, anstatt das gesamte Objekt selbst mit sich herumzutragen.

Sie können auch die Größe der Sitzung in der Datei INI erhöhen und prüfen, ob dies einen Unterschied macht.

2
AndyMcKenna

Bitte stellen Sie sicher, dass die Klassendefinition "Vorlage"des Objekts, das Sie bearbeiten möchten, wurde vor geladen ...
Ich denke, include 'inc/template.class.php'; soll die Definition der Klasse Template laden?
Dann ist das Include möglicherweise fehlgeschlagen. Versuchen Sie stattdessen required .
<?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();

2
VolkerK

ich habe auch versucht, Objekte in Session-Variablen zu speichern. und ja, ich hatte das gleiche Problem wie MackDaddy. und es wird gelöst, indem das Include der Klasse auf das erste verschoben wird.

so..

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

hat funktioniert

aber nicht...

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

hmm ... frage mich, was das Vernünftige ist? und was ist, wenn wir zwei oder mehr verschiedene Objekte haben? welches kommt zuerst?

1
resting

In meinem Fall war die Reihenfolge, in der ich meine Dateien einfügte und die session_start() aufgerufen hatte, falsch, wie Carlos in seiner Antwort erwähnte.

Aber ich konnte die Bestellung nicht reparieren.

Diese Problemumgehung hat für mich funktioniert:

$_SESSION["template"] = unserialize(serialize($_SESSION["template"]))
0
Savenkov Alexey