Req #48673 [Com]: Make session serialization functions available to php
| From: | not-bogus at example dot com | Date: | Tue, 23 Aug 2011 07:53:43 +0000 |
| Subject: | Req #48673 [Com]: Make session serialization functions available to php | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-162836@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=48673&edit=1
ID: 48673
Comment by: not-bogus at example dot com
Reported by: joey at blouzar dot com
Summary: Make session serialization functions available to
php
Status: Bogus
Type: Feature/Change Request
Package: Session related
Operating System: All
PHP Version: 5.2.10
Block user comment: N
Private report: N
New Comment:
This is a reasonable Feature Request. Why was it marked Bogus?
There is a whole slew of poor userland implementations in the PHP Manual. Being able to reliable and
safely decode serialized session data into an array instead of into $_SESSION would make a lot of
that poor code obsolete.
Previous Comments:
------------------------------------------------------------------------
[2011-01-02 05:21:04] joey at blouzar dot com
There are serialize/unserialize functions but they are
not compatible with PHP's default internal
serialization mechanism for sessions. I found many
better ways to achieve what I was trying to achieve
over a year ago but still think that the
session_encode and session_decode functions are
undesirably inflexible.
Here is an example why unserialize is not an a
realistic option with default PHP sessions:
# php -d "suhosin.session.encrypt=Off" session.php
Started session.
$_SESSION set to:
array(2) {
["a"]=>
int(1)
["b"]=>
int(2)
}
Closed session with write.
$_SESSION from serialize(): a:2:{s:1:"a";i:1;s:1:"b";i:2;}
$_SESSION from session file: a|i:1;b|i:2;
Attempting to unserialize session:
PHP Notice: unserialize(): Error at offset 0 of 12 bytes in session.php on line
16
bool(false)
As we can see with session_handler set to php
what is produced is not 100% compatible with
the user serialisation functions. Other save
handlers can be set that do not share this
problem. There is no elegant way to use
serialize() in sessions that I am aware
without avoiding the PHP API provided for
session handling entirely.
Additionally, other filters may be in place
that would presumably be handled by
session_encode and session_decode but not
so easily by other means. Using custom
handlers allows the user to easily add
additional features such as compression,
encryption, and locking, but for
serialisation leaves little choice.
There are many ways around this and if you look at
http://php.net/manual/en/function.session-decode.php
you can see some real such kludges. If you don't want
to improve this that is understandable as obviously
it really is a very minor annoyance but I don't think
it is a bogus request :)
------------------------------------------------------------------------
[2011-01-02 02:30:50] jani@php.net
There's already unserialize() and serialize() functions, so what are you really requesting
for..?
------------------------------------------------------------------------
[2009-06-24 11:11:26] joey at blouzar dot com
Description:
------------
The default serialisation scheme in php for session data is different than that provides by php to
the scripting environment. While on one scale it uses the "userland" serialisation format
overall it uses its own scheme that is very hard to parse safely without writing a grammer.
There are existing functions that can serialise/deserialise session data using the session scheme.
However they are not flexible and can lead to risky code. These functions are session_encode and
session_decode. Their short-fall is that they do not let the programmer choose where the data is
deserialised/serialised to or from. It always works with the $_SESSION global.
I submit a simple proposal to provide functions to serialise session data with the same level of
flexibility as the conventional serialisation functions.
An example of how the functions might appear (pseudo):
String|false session_serialize(Array* $in_assoc_array);
Array|false session_unserialize(String $serialized_data);
Or:
Boolean session_unserialize(String $serialized_data,Array* $out_assoc_data);
Of course another suggestion would be to use normal php serialisation on the whole array rather than
just it's members.
Thanks.
Reproduce code:
---------------
$result=$db->query('SELECT * FROM sessions WHERE user='.$recipient);
$oldsession=session_encode();
while($session=$result->object())
{
$_SESSION=array();
session_decode($session->data);
++$_SESSION['menu']['inbox'];
$db->query('UPDATE sessions SET
data="'.$db->escape(session_encode()).'" WHERE
id="'.$db->escape($session->id).'"');
}
$_SESSION=array();
session_decode($oldsession);
Expected result:
----------------
As this is a feature request the code does exactly what is expected. The code here is an example of
the current system. Actually result contains the downfalls of this.
Quick redundant note. This code may not be the best example (one might argue that the counter should
be stored elsewhere) but was the closest one to hand.
Actual result:
--------------
While it works fine it is somewhat risky. Loading the data to the current session is beyond
requirement. If an inexperienced developer were to alter this code it could result in a mistake such
as breaking the restoration of the session that causes the user submitting the post to adopt the
session of the recipient. It is also somewhat inefficient as the existing session data should not
really need to be backed up and restored. I did try just copying the global to another variable and
back again but this somehow resulted in the user being logged in as the recipient. I decided to play
it safe after that and serialize/deserialize it instead.
With a custom save handler it could be possible to implement a security switch. However, this is far
from elegant.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=48673&edit=1