2009-03-02 6 views
5

Ho uno script PHP chiamato in 2 modi da una chiamata Dojo Ajax xhrGet. La prima volta che viene chiamato con un argomento "init" che fa sì che lo script crei un'istanza della classe StateList e legga in un file di nomi di stato.Perché non posso memorizzare un'istanza di classe PHP come variabile SESSION

session_start(); 
@include('StateList.php'); 
require_once('phplog.php'); 

//start executing here 
$comd=$_GET['nexturl']; 
if($comd=="init") { 
$st = new StateList("../data/statestxt.txt"); 
$_SESSION['statefile'] = $st; 
} 

La seconda e altre volte, un'altra chiamata xhrGet passa un argomento "getstate" e il seguente codice tenta di ottenere l'istanza ofr classe StateList dalla matrice SESSIONE.

if($comd =="getstate") { 
$st= $_SESSION['statefile']; 
phplog("size=".$st->getSize()); 

}

Tuttavia, il metodo getSize() non viene mai eseguito, né posso chiamare qualsiasi altro metodo sulla istanza di classe StateList ricostituito.

Si noti che questo è uno script PHP che include la definizione di classe nella parte superiore e quindi i metodi di classe dovrebbero essere noti e disponibili.

Cosa mi manca qui?

+0

Cercare di evitare l'uso di @; scrivi semplicemente il tuo codice in modo che non ci siano errori da sopprimere. –

risposta

1

Potrebbe essere necessario serialize l'oggetto/variabile $ st prima di memorizzarlo. Ciò garantirà che tutto sia salvato nella sessione. Questo è sicuramente il modo di andare per il codice object oriented. Quando si desidera utilizzare nuovamente i dati, è necessario unserialize.

+6

Le variabili di sessione vengono serializzate automaticamente e non serializzate. – outis

14

È necessario includere la definizione di classe prima di chiamare session_start(), altrimenti l'oggetto non verrà deserializzato correttamente e sarà un'istanza di __PHP_Incomplete_Class. Altrimenti quello che hai dovrebbe funzionare bene.

+1

Se sposto la definizione come suggerito, il valore restituito dall'array di sessione è nullo. –

+0

hai display_errors on e error_reporting E_ALL? Puoi assicurarti che il primo bit sia effettivamente in esecuzione ($ comd == "init")? –

0

Se si intende archiviare un oggetto nella sessione, è necessario che sia link text. Ci sono MOLTI problemi con la serializzazione di oggetti in PHP, per non parlare di archiviarli nella sessione. Vi consiglio di non fare tutto questo e di trovare una soluzione diversa per il vostro problema. Se lo farai comunque, dovresti esaminare i "metodi magici" link text che dovresti definire nella tua classe per facilitarne la ricostituzione quando viene chiamato dalla sessione.

0

Avete abilitato session.auto_start? Pagina sessione del manuale afferma che se lo fai, è necessario caricare la definizione di classe in modo diverso:

Se si accende session.auto_start allora l'unico modo per mettere gli oggetti in vostre sessioni è quello di caricare la sua definizione di classe utilizzando auto_prepend_file in cui si carica la definizione della classe altrimenti si dovrà serializzare il proprio oggetto e successivamente serializzarlo.

http://php.net/manual/en/intro.session.php

Come quella pagina dice, la serializzazione/deserializzazione dell'oggetto saranno generalmente fatto automaticamente da PHP, ma avendo session.auto_start abilitato cambierà questo.

+0

No, non è abilitato. –

1

Questa è una di quelle cose che è difficile eseguire il debug in isolamento. La memorizzazione di oggetti istanziati in PHP Sessions è sempre un po 'complicata e non garantita al 100%. Ecco alcuni suggerimenti generali per il debug che possono aiutarti a capirlo.

Innanzitutto, controllare il registro degli errori di apache. Stai ricevendo un "metodo chiamato errore non oggetto"?Se è così, questo significa che non stai recuperando un oggetto dalla sessione. In caso contrario, c'è un errore che indica che la chiamata al metodo sta fallendo per un altro motivo?

In secondo luogo, controlla per vedere cosa stai veramente uscendo dalla sessione.

if($comd =="getstate") { 
    $st= $_SESSION['statefile']; 
    //get the class of st 
    phplog("instance=".get_class($st)); 

    //get a reflection dump of st 
    $ref = new ReflectionClass($st); 
    $string = $ref->__toString();  
    phplog("reflection=".$string); 
} 

In terzo luogo, osservare il valore di stringa serializzato che viene archiviato nella sessione stessa. Stai effettivamente memorizzando un oggetto serializzato? Nel vostro ambiente dev, impostare il valore session.save_path ini in php.ini per qualcosa come/tmp, (o utilizzare il metodo ini_set a fare la stessa cosa):

session.save_path = "/tmp" 

e quindi esaminare i file creati in/tmp (o qualunque cartella). Si dovrebbe vedere una stringa che inizia con:

statefile:O:.......... 

Il nome della classe che un'istanza l'oggetto apparirà anche in là, così come i valori salvati in proprietà.

0

Prova questo:

include('StateList.php'); 
    require_once('phplog.php'); 
    // start your session after including your class file 
    session_start(); 

    //start executing here 
    $comd=$_GET['nexturl']; 
    if($comd=="init") { 
    $st = new StateList("../data/statestxt.txt"); 
    $_SESSION['statefile'] = $st; 
    } 

    if($comd =="getstate") { 
    // the ampersand creates a reference, preserving any further changes to your session data 
    $st = &$_SESSION['statefile']; 
    phplog("size=".$st->getSize()); 
    } 
+0

codice interessante. penso che potrei fare un tentativo. – transilvlad