ZF-1743: Zend_Session_Namespace does not persist new slice data
Description
I'm having an issue with Zend_Session on PHP 5.1.6:
////////////////////////////////////////////////
$auth = new Zend_Session_Namespace( 'auth' );
...
...
...
The Auth namespace above works well and so far, so good. Its values get reloaded on subsequent page loads. Session is setup properly and it works.
However, getting another slice (page) of the session does not persist the new slice on the next page load (the auth slice still works fine). Hence, a new value is getting generated for each page-load:
////////////////////////////////////////////////
if ( ! $value = getPage( $key )) // Always fails
{
$value = generatePageValue(); // And a new value is generated
setPage( $key, $value ); // Save to session (but it does not get saved as it does not reload on next page)
}
////////////////////////////////////////////////
function getPage( $key )
////////////////////////////////////////////////
{
$page = new Zend_Session_Namespace( 'page' );
//
if ( isset( $page->$key ))
{
$key = $page->$key;
//
if ( isset( $key[ 'value' ] )
return $key[ 'value' ]
}
//
return '';
}
////////////////////////////////////////////////
function setPage( $key, $value )
////////////////////////////////////////////////
{
$page = new Zend_Session_Namespace( 'page' );
$data = ( isset( $page->$key ) ? $page->$key : array());
//
$data[ 'value' ] = $value;
$page->$key = $data;
}
In the above 'page' namespace, it is always returning an empty value on getPage() and hence saving a new value to the session on every page load. We even tried the Zend_Session_Namespace::SINGLE_INSTANCE mode, too but no luck. Here is the old code that used to work well without a problem:
////////////////////////////////////////////////
function getPage( $key )
////////////////////////////////////////////////
{
if ( isset( $_SESSION[ 'page' ][ $key ][ 'value' ] ))
return $_SESSION[ 'page' ][ $key ][ 'value' ];
//
return '';
}
////////////////////////////////////////////////
function setPage( $key, $value )
////////////////////////////////////////////////
{
$_SESSION[ 'page' ][ $key ][ 'value' ] = $value;
}
I guess I used a version-safe syntax on namespace component. The updated documentation reads the issue with PHP version, like so:
Version Pre-5.2 syntax (works on all versions):
if ( isset( $page->$key ))
{
$key = $page->$key;
//
if ( isset( $key[ 'value' ] )
return $key[ 'value' ]
}
Version 5.2+ syntax (does not work under 5.2):
if ( isset( $page->$key[ 'value' ] ))
{
return $page->$key[ 'value' ]
}
I used the version pre-5.2 syntax on both - auth and page slices. It works on auth slice gracefully but fails on the page slice.
I tested it on a temporary installation of PHP 5.2.3 (another machine) and it works fine. But I really need to make this work on 5.1.6 as our dev environment would take ages to upgrade to 5.2.x. I don't see why this should not work on 5.1.6 given that I am using pre-5.2 syntax that is supposed to work on all versions.
On another note, I've noticed if I set the option as under:
Zend_Session::setOptions( array(
'name' => 'MySID' )
);
but not set the session.name inside php.ini, the first session name is generated as PHPSESSID and subsequent names are generated as per the above setting (MySID). I was able to see the session_name for each namespace object created by doing:
echo session_name();
However, if I set the value in php.ini, session name is generated properly for each namespace. And so, I ended up setting the name in the ini file. Don't know if this is an issue with 5.1.6 or Zend_Session and thought you might like to take a look at this one, too.
Comments
Posted by Ralph Schindler (ralph) on 2007-07-31T13:51:26.000+0000
Shekar, I am trying to build a testable testcase for this so that i can apply it to all verisons of php supported by zend framework.. does this look like it describes the problem well?
can you confirm this produces the problem on your version?
-ralph
Posted by Shekar Reddy (zendfw) on 2007-08-01T13:55:29.000+0000
Hi Ralph,
The following test-cases work well on v5.2.3 but fail on v5.1.6:
You marked my issue 1743 as a duplicate of http://framework.zend.com/issues/browse/ZF-1385 but I'm not sure if it is. Furthermore, my issue comprises of two problems; one being the above, and the other pertaining to setOptions('name') for session-name at its bottom.
HTH
Posted by Shekar Reddy (zendfw) on 2007-08-02T13:51:05.000+0000
Hi Ralph,
Forgot to mention that ideally, the pre-v5.2 syntax should work on all versions as expected.
On another note, I consider it double-standards to advise the developers to use one syntax for pre-v5.2 and another syntax for v5.2 - unless the ZF raises the minimum PHP version to 5.2. Its more confusing and there will be frequent questions on the list why the Zend_Session logic is not working even if its documented clearly and even if its an issue with the version of PHP they are using. I suggest that we simplify the session component and offer Zend_Session out of the box without dependency on the namespace subcomponent. However, those who wish to use the namespace subcomponent may still use it if their version of PHP is compatible with the syntax they're going to use. Here is my suggestion that supports optional namespaces and multi-dimensional nodes that should suffice most applications - including even the complex ones:
What do you think of the above...?
Posted by Ralph Schindler (ralph) on 2007-08-02T14:02:53.000+0000
Shekar, Ive done some digging and using a standard suggested test script, was able to identify the problem to only 5.2.0
here is the code i used:
And the output of runs:
Again, right now we are only talking about modification of Namespace variables, (not the "name" issue you also mentioned above)
See if this demonstrates the problem, my run output is right above. -ralph
Posted by Ralph Schindler (ralph) on 2007-08-02T14:14:47.000+0000
As a 5.2.0 only workaround:
Posted by Darby Felton (darby) on 2007-08-02T15:12:38.000+0000
I get results consistent with Ralph's - success for versions 5.1.4 (WinXP), 5.2.1 (Ubuntu), and 5.2.3 (RHEL 3).
Posted by Shekar Reddy (zendfw) on 2007-08-02T15:58:55.000+0000
Hi Ralph/Darby,
I work on v5.1.6 on XP where the script did not work. It worked on 5.2.3 on XP, too. Regret, I have no way of testing it on other versions.
It's strange it works on 5.1.4, 5.1.6 but not on 5.2. Does it mean PHP was fine on 5.1.4 and 5.1.6 but broken in 5.2 in this respect? Is there a guarantee it would not be broken in future versions of PHP? It wouldn't be graceful for the session component if it does!
In any case, the methods I suggested above for the Zend_Session component to make it independent of the namespace subcomponent are backwards compatible and are meant to be in addition to the ones that already exist in the session component.
Regards,
Posted by Ralph Schindler (ralph) on 2007-08-02T16:39:35.000+0000
Shekar, I just downloaded php 5.1.6 for xp and was able to sucessfully run this script:
And get these expected results:
Are you using this test script or the one you posted above? B/c i notice the one you post above does not explicitly call Zend_Session::start() even though you are printing $_SESSION before the first namespace object is created (which implicitly calls start).
Overall, before discussing code changes, we really need to identify the problem, and to which version of php it pertains to. Once we figure that out, then we can talk about what changes to the codebase need to happen in order to fix outstanding problems.
Posted by Ralph Schindler (ralph) on 2007-08-02T16:55:05.000+0000
Note: other projects have also come across this problem and have fixed and suggested to move up to 5.2.1. 5.2.0 is simply broken when it comes to __get() behavior, and forcing a referenced return does not work for that version.. This should be taken into consideration when a decision needs to be made about whether or not fix's need to be applied to the codebase..
References:
http://trac.symfony-project.com/trac/ticket/1376 http://weierophinney.net/matthew/archives/…
Posted by Shekar Reddy (zendfw) on 2007-08-06T09:18:07.000+0000
Hi Ralph,
Yes, Zend_Session::start() is called elsewhere BEFORE the script is executed. It's the same script that is run on 5.1.6 and 5.2.3 without any changes; otherwise, code on 5.2.3 would not succeed, either (I'm getting results as desired on 5.2.3)! But I'm not sure why my PHP 5.1.6 is failing - maybe something wrong with my installation/configuration. It could be a DLL mismatch or a corrupted download or something that I'm not sure.
I'm gonna have to re-download/re-install/re-try it. I'll let you know soon...
Posted by Ralph Schindler (ralph) on 2007-08-08T10:53:42.000+0000
Modified my test script to include unnamed array modification and creation:
Script and test run below:
Posted by Shekar Reddy (zendfw) on 2007-11-07T01:12:42.000+0000
I re-downloaded PHP 5.1.6 and did a binary diff on all the files with those installed on my machine and found all of them to be identical. I guess this is just an isolated case - the reasons for which are unknown for now. Since you and Darby are stating it works on 5.1.6, let safely assume that 5.1.6 does not have any issues except for my isolated case.
Thanks,
Posted by Ralph Schindler (ralph) on 2008-02-04T11:06:16.000+0000
Closing as not an issue right now, have done due diligence in finding the core of the issue, but it seems it only affects a 'bad' version of php.
-ralph