2009-06-28 17 views
33

Me aparece un error que no sé cómo solucionarlo, por lo que me pregunto si podría obtener ayuda.Sesión de PHP con un objeto incompleto

Este es el error

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 

me sale este error en la función process_form(). Entonces, lo que obtengo de esto es que, pensando que no cargué la clase para la plantilla. Que de hecho lo hice en la parte superior. El include 'inc/item.class.php'; ¿Debo volver a incluirlo en la función?

Aquí está el código de la página en particular con el error. Puedes ver que tengo todo incluido como debería ser. ¿Dónde me he equivocado?

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

¿Cuál es su archivo php.ini para configurar session.auto_start? –

Respuesta

64

Falta la serialización/deserialización de su clase de plantilla.

Echa un vistazo aquí para un working example que di sobre otra cuestión tuya.

Por ejemplo, es probable que quieren esto:

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

y

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

Editar:

leer su comentario acerca de cómo mover a la parte superior da una pista.

La serialización/deseterialización automática se produce cuando se llama al session_start().
Eso significa que el orden en que incluye sus archivos y llame al session_start() es muy importante.

Por ejemplo:

Esto sería un error:

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

Si bien esto sería correcto:

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

Ahora, veo en su ejemplo que está en el orden correcto , pero también noto que usted hace muchos otros incluye antes de incluir template.class.php

¿Lo haría? Es posible que uno de ellos incluya (quizás prep.php o header.class.php) ¿llama también al start_session()?
En caso afirmativo, ese era su problema (session_start() siendo llamado antes de su template.class.php).

+4

Por lo que entiendo, PHP serializa automáticamente un objeto si lo agrega a una sesión y luego lo desercializa si debe asignarlo a una variable. Al menos eso es lo que he leído aquí: http://www.devshed.com/c/a/PHP/Working-with-MySQL-and-Sessions-to-Serialize-Objects-in-PHP/1/ Todo lo relacionado con mi objeto funcionaba bien excepto esto. – MackDaddy

+0

Tomando el ejemplo que te di en la otra publicación y eliminando el serialize/unserialize obtendrás esto: Unserialized $ template: object (__ PHP_Incomplete_Class) # 1 (3) {...} –

+0

No tomes mi palabra intente con el código que le di como ejemplo, intente agregar un/serialize a su código y vea si funciona :) –

2

¿Qué tan grandes son los objetos que está poniendo en la sesión? Obtuve un error similar una vez cuando mis objetos eran más grandes que el espacio que habíamos asignado para la sesión en el archivo php.ini. Si el objeto era demasiado grande, volvería a estar vacío cuando no debería haberlo sido.

Después de eso, comencé a almacenar el PK del objeto en la sesión y lo busqué si lo necesitaba en lugar de transportar todo el objeto en sí.

También podría aumentar el tamaño de la sesión en el archivo INI y ver si eso hace la diferencia.

2

Por favor asegúrese de que la definición de la clase " Plantilla" del objeto que está intentando operar en se cargó antes ...
supongo include 'inc/template.class.php'; se supone que debe cargar la definición de la plantilla de clase?
Entonces quizás la inclusión falló. Pruebe require en su lugar.
<?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();

+3

'require' y' include' son idénticos en todos los sentidos, excepto en cómo manejan el error. Ambos producen una advertencia, pero 'require' da como resultado un error fatal. –

1

intenté almacenar objetos en la variable de sesión también. y sí, tuve el mismo problema que MackDaddy. y se resuelve moviendo la inclusión de la clase a la primera.

así ..

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

trabajaron

pero no ...

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

hmm ... se preguntan cuál es el racional? y ¿y si tenemos 2 o más objetos diferentes? ¿Cuál viene primero?

9

Cuando session_start() en php $_SESSION array se rellena con los objetos correspondientes. Esto significa que todas las interfaces deben estar disponibles (requieren). Si la sesión ya ha sido iniciada previamente por otro script (por ejemplo, framework) que no tiene visibilidad en las interfaces, los objetos en $ _SESSION estarán incompletos, y hacerlo de nuevo session_start() es inútil porque la sesión ya se ha iniciado. Una posible solución es usar el método session_write_close(), luego session_start() que comienza de nuevo poblar $_SESSION, pero con visibilidad en la interfaz, por lo que su objeto en $_SESSION será bueno.

+0

Brillante. Esto resolvió un problema que tuve al usar mi propia clase de carrito de compras (que usa $ _SESSION como contenedor para el carro) en combinación con Wordpress (que ya había comenzado la sesión). ¡Gracias! – cjs1978

5

He publicado mi respuesta en un similar question, volviendo a publicarla porque también responde a esta.

PHP serializa sus sesiones utilizando los métodos integrados serialize y unserialize. serialize de PHP tiene la capacidad de serializar objetos PHP (también conocidos como instancias de clase) y convertirlos a cadena. Cuando unserialize esas cadenas, las convierte de nuevo esas mismas clases con esos valores. Las clases que tienen algunas propiedades privadas y desean codificar/decodificar eso o hacer algo complejo en su serialización/deserialización implementan la clase Serializable y agregan los métodos serialize y unserialize a la clase.

Cuando unserialize intentos de PHP para unserialize un objeto de clase, pero el nombre de la clase no se declara/necesario, en lugar de dar una advertencia o lanzar una Exception, que la convierte en un objeto de __PHP_Incomplete_Class.

Si no desea que sus objetos de sesión para convertir a __PHP_Incomplete_Class, puede hacerlo por cualquiera que requieren los archivos de clase antes de invocar session_start, o mediante el registro de una función de carga automática.

0

En mi caso, el orden en el que incluí mis archivos y llamé session_start() era incorrecto, como Carlos mencionó en su respuesta.

Pero no pude arreglar el pedido.

Esta solución funcionó para mí:

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