views:

2996

answers:

5

I have a PHP script that is called in 2 ways from a Dojo Ajax xhrGet call. The first time it is called with an "init" argument which causes the script to create an instance of the StateList class and read in a file of state names.

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;
}

The second and further times, another xhrGet call passes a "getstate" argument and the following code tries to get the instance ofr the StateList class from the SESSION array.

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

}

However, the getSize() method is never executed, nor can I call any other method on the reconstituted StateList class instance.

Note that this is one PHP script that DOES include the class definition at the top and thus the class methods should be known and avaialble.

What am I missing here?

A: 

You may need to serialize the $st object/variable before you store it. This will ensure that everything is saved to the session. This is definitely the way to go for object oriented code. When you want to use the data again, you must unserialize it.

scheibk
+4  A: 

You need to include the class definition before you call session_start(), otherwise the object will not be deserialized correctly and will be an instance of __PHP_Incomplete_Class. Otherwise what you have should work fine.

Tom Haigh
If I move the definition as you suggest, the value returned from the session array is null.
do you have display_errors on and error_reporting E_ALL ? Can you make sure that the first bit is actually running ($comd=="init")?
Tom Haigh
A: 

If you are going to store an object in the session it must be link text.There are a LOT of problems with serializing objects in PHP, let alone storing them in the session. I recommend against doing this altogether, and finding a different solution for your problem. If you are going to do it though, you should look into the 'magic methods' link text which you should define in your class to facilitate it's reinstantiation when it is called from the session.

robmerica
A: 

Do you have session.auto_start enabled? The manual's session page states that if you do, you have to load the class definition differently:

If you turn on session.auto_start then the only way to put objects into your sessions is to load its class definition using auto_prepend_file in which you load the class definition else you will have to serialize your object and unserialize it afterwards.

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

As that page says, the serialization/unserialization of the object will normally be done automatically by PHP, but having session.auto_start enabled will change this.

Chad Birch
No it is not enabled.
A: 

This is one of those things that's hard to debug in isolation. Storing instantiated objects in PHP Sessions is always a little tricky, and not 100% guaranteed to work. Here's some general debugging tips that may help you figure this out

First, check your apache error log. Are you getting a "method called on non-object error"? If no, this means you're not getting an object back out of the session. If not, is there an error that indicated your method call is failing for another reason?

Second, check to see what you're really getting out of your session.

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);
}

Third, look at the serialized string value that is being stored in the session itself. Are you actually storing a serialized object? In your dev environment, set the session.save_path ini value in php.ini to something like /tmp, (or use the ini_set method to do the same thing)

session.save_path = "/tmp"

and then examine the files created in /tmp (or whatever folder). You should see a string that starts

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

The name of the class that instantiated the object will also be included in there as well, as well as values saved to properties.

Alan Storm