Jump to content

Storing a DateTime object in $_SESSION yields an error


jhsachs

Recommended Posts

I just ran into grief while trying to store a DateTime object in the SESSION variable. When I tried to use the stored value I got the error message "The DateTime object has not been correctly initialized by its constructor."

 

I initially assumed that objects can't be stored in SESSION because there's no way to serialize and deserialize them for storage between scripts. But I've found posts by other people who have done this with without problems.

 

If it works for others, why isn't it working for me? Is there something special about the DateTime class that prevents the PHP engine from serializing it?

 

Here's a little script that demonstrates the problem (in PHP 5.2.5 under Windows XP):

 

<?php
session_start();

if ( key_exists( 'd', $_SESSION ) ) {
   $d = $_SESSION['d'];
   echo "<br/>The value of 'd' is " . $d->format('m/d/Y');
}
else {
   echo "'d' has no value yet.";
}

$d = new DateTime('2011-08-01');
$_SESSION['d'] = $d;

$e = $_SESSION['d'];
echo "<br/>The value of 'd' has been set to  " . $e->format('m/d/Y');

?>

 

The first time the script is run it does not display "The value of 'd' is..." because $_SESSION['d'] does not exist. It sets the value, then retrieves it intact and displays it.

 

The second time the script is run it tries to retireve the value but apparently gets an invalid one and displays the error. Then it sets, retrieves, and displays the value again.

Link to comment
Share on other sites

The code works as expected for me on a Win xp, php5.3.8 system.

 

Either there is a bug in your php version or there is a problem with the session. You could open the session data file in your programming editor to see what is being stored.

 

FYI - the serialize/unserialize issue applies to resources, not objects, provided you have not stored a resource in an object.

 

Note: You don't need to keep copying to/from the session variable, just use $_SESSION['d'] = new DateTime('2011-08-01');

Link to comment
Share on other sites

@MasterACE14, all of the following are valid uses of a session variable -

<?php
$_SESSION['id'] = "abc";

$_SESSION['id'] = array(1,2,3);

$d = new DateTime('2011-08-01'); // could also be a user written class (class definition must exist before the session_start statement)
$_SESSION['d'] = $d;

$_SESSION['d'] = new DateTime('2011-08-01'); // could also be a user written class (class definition must exist before the session_start statement)

 

Link to comment
Share on other sites

I'll summarize what has happened so far.

 

The example failed for me under Windows XP and PHP 5.2.5.

 

I have since tested it under Linux and PHP 5.2.14, where it fails.

 

PFMaBiSmAd reported that the example works for him under Windows XP and PHP 5.3.8. He suggested that I look at the session data file to see if there is something wrong with the session. I could not find documentation for the session data file, so I haven't tried that yet: where is it, and how can I tell whether something is wrong with it or not? Meanwhile, though, the fact that my example fails under a different OS and version of PHP suggests to me that something else is going on.

 

I've got another odd problem which I didn't think was related to this one, but I'm beginning to suspect it may be, so I'll mention it now. The DateTime class's diff function is undefined; when I call it, I get a run time error. In fact, I can get the error by running the first example from php.net's manual page for DateTime::diff. Yet at least some of DateTime's other methods are defined (specifically, format and the constructor), and appear to work properly.

Link to comment
Share on other sites

Good catch, PFMaBiSmAd.

 

I didn't think to check the release version because diff seems like an utterly basic method for this class.

 

Without it, how do I determine whether one date is later than another? The only way I can think of is the brute-force way: format the years and compare them, if they're equal format the months and compare them, etc.

Link to comment
Share on other sites

@MasterACE14, all of the following are valid uses of a session variable -

<?php
$_SESSION['id'] = "abc";

$_SESSION['id'] = array(1,2,3);

$d = new DateTime('2011-08-01'); // could also be a user written class (class definition must exist before the session_start statement)
$_SESSION['d'] = $d;

$_SESSION['d'] = new DateTime('2011-08-01'); // could also be a user written class (class definition must exist before the session_start statement)

 

 

wasn't aware this could be done. Thanks for the insight!

Link to comment
Share on other sites

The datetime class is fairly new and immature code. I suspect in your case that you are up against a bug in the serialization or un-serialization of it that is occurring when the session data file is saved or retrieved.

 

I just found this in the php5 change log for 5.3.0 - Added new date/time functionality: support for serialization and unserialization of DateTime objects.

Link to comment
Share on other sites

PFMaBiSmAd, would you tell us what version of PHP you used when you tested my example and it worked? If it was >=5.3, that should nail the problem.

 

It doesn't matter what version he tested it with, the change log says 5.3.0  so 5.3.0 or above will work.

Link to comment
Share on other sites

premiso, with respect, it does matter. We don't know that using 5.3 is a sufficient condition for making the script work. We don't even know that it's a necessary condition, because we don't know what the added "support for serialization and unserialization of DateTime objects" is, or what it was added to fix.

 

Assuming you understand everything about a situation is always dangerous, but it is especially dangerous when you are trying to correct a problem that you know you don't understand!

Link to comment
Share on other sites

Just because you are ignorant and cannot be arsed to understand what serizalization and unserialization of an object means does not mean I cannot be. And yes, I do fully understand what that statement means, as apparently does PFMaBiSmAd, or else he would not have posted it.

 

So yea, if you do not know something, research it instead of being hand fed information, or try it for yourself and stop being lazy.  It really is not hard to get another version of PHP running on a test box or VM or just be even installing it to a different folder. So yea.

 

Thanks!

Link to comment
Share on other sites

Serialization of DateTime objects was only added to the language in PHP 5.3.0.

 


 

Just to show you that's the case, the following script was executed on many different versions.

 

<?php

$dt = new DateTime('2011-09-01', new DateTimeZone('UTC'));
$serialized = serialize($dt);
$unserialized = unserialize($serialized);
echo $unserialized->format('r');

?>

 

The results were:

 

-- 5.2.0 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.1 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.2 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.3 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.4 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.5 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.6 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.8 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.9 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.10 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.11 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.12 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.13 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.14 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.2.15 --
Warning: DateTime::format(): The DateTime object has not been correctly initialized by its constructor in /tmp/fwY5gl on line 6

-- 5.3.0 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.1 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.2 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.3 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.4 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.5 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.3.6 --
Thu, 01 Sep 2011 00:00:00 +0000

-- 5.4.0 --
Thu, 01 Sep 2011 00:00:00 +0000

-- trunk --
Thu, 01 Sep 2011 00:00:00 +0000

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.