|
|

|
PHP4 Sessions with PHPlib using session4_custom.inc*Preface: Why the damn thing is happened.Many people say that we do not need PHPLib session interface anymore
since session support is now built in PHP4. I have some objections. The first is that many many applications was written using PHPLib, so
the rewrite should be done. The second is that the Session class is really very convenient way to
manage sessions. And it, of course, could be used as a framework for
session management, while using new PHP4 session API, that, of course,
is much more fast than the old PHPLib Session API. Moreover, there is a lot of stuff in the PHP session module that could
be tweaked. You can tweak it using php.ini directives. You can also tweak
it using session api functions. There are many of them. I doubt that it is
convenient to call them explicitly on every page. PHPLib Session class can
do it for you using user-supplied values, and one $sess->start() call can do
all custom tweaking and start the session with the parameters you want. The third is that PHPlib has always had session data storage abstraction. Native
PHP4 session module gives you a choice to use either files or shared memory as
the storage for session data. If you want to store the data anywhere else, you
should supply your custom functions. PHPLib has had this functions for years -
they are in CT_* classes. Why not use them as our custom storage containers? So, given this arguments, we could talk about something that I call the
'session abstraction', similar to the DB abstraction. Using this class you can
tweak almost every session parameter - cookie headers, cache management, session
name, storage mechanism, url rewriting .... from one place - your
custom Session subclass declaration. Of course, there would be some overhead
compared to using PHP4 session functions explicitly. But I estimate that overhead
as negligible, while the benefits are too lucrative :) How session4_cust.inc worksThe new Session object is written as a wrapper over native PHP4 session
handling functions. It was written with compatibility in mind, while some
of the compatibility somewhere was sacrificed in favor of performance.
The class can use either native PHP4 session storage (currently 'files'
and 'mm' modules) or PHPLib custom storage containers, implemented in
CT_* classes, that currently can store data in a SQL database, DBM files,
LDAP directories, and anything else, if you provide necessary CT_Something class. The storage mechanism is set by the $module property (that is missing from the
old Session). The $module could take 'user', 'files' or 'mm' value. If the value is
'files' or 'mm', the Session will set its storage module to a respective native
PHP4 session storage module. If you use 'files' module you can set $save_path property
to a value of the directory where you intend to store session data. Otherwise
default value from php.ini will be used. If $module is set to 'user', the PHPLib's custom CT_* container will be used. To
define which custom container will bw used, set $that_class in your Session subclass,
like you do with the old Session. I suppose that your subclass that works with the
old Session, will work with the new one. If the custom storage is used, session_set_save_handler() will be called during
session startup. If you use PHP version earlier then 4.0.4, use version 1.3 of the
session4_custom.inc from CVS. Since version 4.0.4 the session_set_save_handler() can
take array ($class, 'method') arguments, and this behavior is used in session4_custom.inc
after version 1.3, but it is not compatible with previous versions of PHP. I'd recommend
you to upgrade, since version 1.3 of session4_custom.inc lacks many features that are
present in the current version. The class does some session tweaking using supplied values. It modifies session
cookie header using $cookie_path, $cookiename, $lifetime and $cookie_domain properties.
the behaviour is similar to the old classs'. Caching behaviour is managed by $allowcache
and $allowcache_expire methods, similar to the old class.
PHPlib Session has url() and friends to append session_name=session_id pair to an url if
the session cookies are not used. This class has similar functionality, but has some
changes as well. First, $mode and $fallback_mode are not necessary - their handling is
done automatically, since PHP4 session engine will always try to set a session cookie, if
session.use_cookies in the php.ini is set to true. If you don't like session cookies, set
this parameter in the php.ini to 0, false or Off. There is currently no possibility to
change this parameter from within the script. Another change is that now url() and friends respect the $trans_sid_used property settings.
Set $trans_sid_used to true if you are ABSOLUTELY sure that trans_sid feature works
in your setup. There is a session.use_trans_sid parameter in php.ini, but it shows me 1
even when i don't compile PHP with --enable-trans-sid option. So, if you are sure,
set $trans_sid_used property to true value, and url() and friends won't append anything
to your urls, get_hidden_session() will return nothing, and all this will be done by
trans_sid feature. get_id() now does not respect any value passed to it, actually it is now get_id(void).
This is done because native PHP4 session mechanism now determines the session id itself. All the things above configured by default in a manner that they don't break existing
PHPLib-based applications. The default storage method is 'user', that will cause using
PHPLib's custom storage containers. The $trans_sid_used method is not set to true. Cache
and cookies parameters are the same, as in the Session class from PHPLib ver. 7.2c. Differences from older PHPlib sessionsThe main differences from previous PHPLib Session are the auto_init file use, session data
format, serialize() and thaw(), use of page_close() and use of the User class. Serialize(), thaw(), register(), and the new data format.The new Session the serialize() behavior is changed. Now serialize() is the wrapper over
native session_encode(), that returns session data in a native serialize() format or WDDX
format, corresponding to the php.ini's session.serialize_handler. It much more faster, then
using the old serialize(), that, using recursive calls, produced plain PHP code that should
be feed to eval() in thaw() then. The $persistent_slots in objects that should be registered in a session are no longer
respected - all the class properties are now saved with the session. thaw() is used as the custom session read handler now. It does not actually 'microwave'
frozen variables, it just pass serialized session data to the session engine. To reimport
session data use unserialize() (which is a wrapper over the session_decode() itself).
Register() does not fill $pt array, it uses native session_register() instead. The session
data is actually a serialized representation of $HTTP_SESSION_VARS array. So, you can not
register any class property without registering the class itself. Register() can register
only global variables. E.g. the old Session registers $sess->in property as a marker,
whether auto_init file was used or not. That is not possible with the new register().
(Auto_init issues will be covered shortly) and, as you could see, the new session data format is uncompatible with the old one. But
I suppose this should not affect any PHPlib-based applications. The auto_init file was called if $sess->in is false. $sess->in was registered as the session
variable, and if the auto_init file was called (at session initialization), it was set to
true, and the auto_init file was not called in subsequent requests. But, as it was explained
before, $sess->in can not be respected now, since it won't be saved as the session variable.
Auto_init file will be called at every request. So, you'll need to modify your auto_init
file so it could check, if the things that should be initialized only once have been
already initialized. Eg:
if (!$sess->is_registered('cart')) {
$cart = new Cart;
$cart->start();
}
The native PHP4 session engine automatically saves the session data at script shutdown. To
prevent multiple attempts to save the session data you should disable call to $sess->freeze()
in page_close() (see page.inc, the example in the current CVS). Actually, if you don't use
the User class, you don't need page_close() at all anymore. The bad side that you can not
currently manage read-only sessions. In a framed page you could call page_close() only in
one frame, while other frames used the session read-only. Otherwise there are chances
that frames will spoil your application by attempting to write session state at the same
time, causing DB errors, or rewriting the data registered in a neighbor frame. The feature
request for read-only session possibility is sent to the PHP Group, so the situation can
change shortly. The User class had been designed as an extension of the Session class. It had worked ok
with the previous Session classes. But The new Session class is incompatible with the old
User, since many methods in the current Session are the wrappers over native session
functions, and they can not be used in the User class. I supplied a User class that should
work with this Session variant - see user4.inc. It is no more extended the Session, while,
of course, has the same API functions as earlier. It now uses native serialize(), which
is much faster, as it said before, and $persistent_slots in objects are not respected
anymore. That is also apply to the $classname properties, as serialize() now determines
the names of serialized classes automatically.
The data format of the saved user data, of course, also has changed.
A simpliest program to convert old user data to the new format:
(Call it with the *OLD* user class.)
$db = new DB_Sql;
$query = "SELECT sid FROM active_sessions
WHERE name = 'Your_user_class' ";
while ($db->next_record()) {
$user = new Your_User_Class;
$user->start($db->f('sid'));
$PHPLIB_USER_VARS = array();
while (list ($key) = each ($user->pt)) {
$PHPLIB_USER_VARS[$key] = $$key;
}
$value = serialize($PHPLIB_USER_VARS);
$user->that->ac_store($user->id, $user->name, $value);
// don't call page_close()
}This should convert all the user data in the table to the new format (I guess :)). * Adapted from the original README_session4_custom by Maxim Derkachev <kot@books.ru> Editors note: As an explaination to the confusion regarding two implementations of PHP 4 session class I quote the following
from an email written to the PHPlib mailing list by Max
nrh> Also, can someone tell me what *exactly* max's aptches are
nrh> in the php-lib cvs tree? I still haven't the foggiest what
nrh> the frell is missing. Begin to feel stupid, quite I do.
Well, it's a source of many troubles, misunderstanding and
tricky "walkthroughs", so I'll try to explain what's exactly
going on there. History first. More than a year ago there was
a discussion in the list on possibility of adaptation of session
class to PHP4 sessions. This brought to us 3 (three!!!)
implementations of native sessions with PHPLib API. The first was
by Teodor Cimpoesu, who, as he noted, did a quick and dirty hack
to show that this is possible. The class was mainly old session
class with some parts changed to calls to PHP4 session API, the
other parts (storage, SID propagation and such) just commented out.
The second was by Barendt Scholtus (excuse me, Barendt, if I
misspell), who did the similar job to Teodor, but also changed
user.inc and page.inc in the similar way. He named his effort as
phplib4, and it remains by that name in the CVS now in the unsup
directory. Both implementations just used to be simple and limited
wrappers over PHP4 session module, conforming to the PHPLib API.
Then, I introduced my session4_custom, which was almost fully
rewritten implementation, which was intended not only to conform to
the PHPLib (public) API and use native PHP4 session module, but also
provided a custom save handler, which used PHPLib's CT_*-style
containers as a session data storage, and an interface to the php.ini's
session module settings from within the Session class. Session4_custom
could not only store data in the CT_* containers (custom save handler),
but also use native save handlers - files, mm and so on. Also, because
of the incompatibilities of the new session4_custom with the old
User class ideology, I introduced the new rewritten User class - User4,
which was no longer depend on Session, with compatible public API but
very different guts. Prepend.php & page.inc were also changed a bit
to reflect the session changes.
Then, Ulf Wendel came and said he need clean and working class
urgently. He began to hack session4_custom. He splet the
Session4_custom class in two parts, the first class with common session
API (now in session4.inc), the second with the custom save handler
(now in session4_custom.inc),which extended the first.
As a result, the Teodor's class had been acquired by the new Session4
class, the session4_custom was simplified, both were put to
php-lib/php/session CVS directory, and Barendt's phplib4 moved to unsup
directory.
So, there's two implementations of PHP4 native sessions in the PHPLib
CVS - session4.inc & session4_custom.inc in the php-lib/php/session
and phplib4 stuff (I see it in various places), which is not mine.
User Contributed Notes PHP4 Sessions with PHPlib using session4_custom.inc*
| 
|
There are no user contributed notes for this page.
|
|
|