Storing classes in a PHP Session with AMFPHP
On October 6, 2008, PHP / HTML - 1 CommentI’m working on a small project with a AMF / PHP backend. The project has different roles and users, and I’m storing the user object in the session of PHP.
Now, according to the PHP manual, it should be possible to store complex objects (and classes) in the session. So when I put the user in the session and then dumped the session to the browser, I was pleased to see everything was in it. So far so good…
But then, strange things started to happen. Whilst the data was in the session, I wasn’t able to get it out easily. To understand what I mean, look at the following examples:
The user has a property ‘projects’, which is an array of projectObjects, which look like this:
class ProjectObject { var $_explicitType = "ProjectObject"; public $name; public $id; public $lastModified; } |
Pretty straightforward.
Now, when i output the projects array using print_r, I get this:
Array ( [0] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => ProjectObject [name] => Test1 [id] => 1 [lastModified] => 1218479521000 ) [1] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => ProjectObject [name] => Test [id] => 2 [lastModified] => 1218479559000 ) ) |
Which is ok (I think).
But when I want to access any of the properties of the project, it will return an error, null or an empty string:
echo $user -> projects[0] -> id; // returns ""; echo $user -> projects[0][id]; //Fatal error: Cannot use object of type _PHP_Incomplete_Class as array echo $user -> projects[0]["id"];//Fatal error: Cannot use object of type _PHP_Incomplete_Class as array |
Weird huh?
The problem is the _PHP_Incomplete_Class, which indicates that the object is not properly stored. After some googling, it turns out you have to define every object / class you want to store in your session before you start the session. So, the solution should be easy, something like this:
require_once(dirname(__FILE__) . "/objects/ProjectObject.php"); session_start(); |
This should work, we define the class, and then start the session. However, somewhere in AMFPHPs internal code (in the Filters.php file to be specific), the session is already started. I could of course alter the Filters file and don’t start the session, or define my object there, but then I would have to do it for every future AMFPHP version, which is not what I want.
Instead, I’ve created a Objectinitializer file, which defines every object I want to put in the session and then call session_start(). Next, I have to make sure that my call is called before the Filters file of AMFPHP is loaded, and that’s it is called somewhere outside the AMFPHP core.
Well, there’s one file in the AMFPHP framework which is more or less designed to have custom code, and it’s the globals.php file.
I’ve defined the servicesPath first, and then call my initializer. This code is executed before any AMFPHP core code, so our object can now be added to the session
$servicesPath = "../projects/testProject/"; $voPath = "../projects/testProject/objects/"; //Start the session, to make sure we're the first require_once($servicesPath . "Objectinitializer.php"); |
By the way, the Objectinitializer looks like this:
/* * This files defines all objects before the session is * started, so we put every object in the session if we * want. */ require_once(dirname(__FILE__) . "/objects/ProjectObject.php"); require_once(dirname(__FILE__) . "/objects/UserObject.php"); session_start(); |
What others have to say:
Thanks!
I had been hunting around and had figured out that AMFPHP had a session_start, but hadn’t figured out how to work around it.
Trying now to decide what penalty I’m paying for storing state in PHP session variables – looks like the disk is being hit alot. Need to figure out if session vars can be saved in memory? dunno just yet…
Any thoughts?
dp
Leave a Reply