8 min read

Introduction

When a user starts browsing a Joomla! web site, a PHP session is created. Hidden away in the session is user information, this information will either represent a known registered user or a guest.

We can interact with the session using the session handler, a JSession object.

When we work with the session in Joomla!, we must not use the global PHP $_SESSION variable or any of the PHP session functions.

Getting the session handler

To interact with the session we use the session handler; this is a JSession object that is globally available via the static JFactory interface. It is imperative that we only use the global JSession object to interact with the PHP session. Directly using $_SESSION or any of the PHP session functions could have unintended consequences.

How to do it…

To retrieve the JSession object we use JFactory. As JFactory returns an object, we must use =& when assigning the object to a variable. If we do not and our server is running a PHP version prior to PHP 5, we will inadvertently create a copy of the global JSession object.

$session =& JFactory::getSession();

How it works…

If we look at the JSession class, we will notice that there is a getInstance() method. It is tempting to think of this as synonymous with the JFactory::getSession() method. There is, however, an important difference, the JSession::getInstance() method requires configuration parameters. The JFactory::getSession() method accepts configuration parameters, but they are not required.

The first time the JFactory::getSession() method is executed, it is done by the JApplication object (often referred to as mainframe). This creates the session handler. It is the application and JFactory that deal with the configuration of the session. Subsequent usage of the JFactory::getSession() method will not require the creation of the object, and thus simply returns the existing object. The following sequence diagram shows how this process works the first time it is executed by the JApplication object:

Joomla! 1.5 Development Cookbook

When the JFactory::getSession() method is subsequently executed, because session will already exist, the _createSession() method is not executed.

The diagram is a simplification of the process; additional complexity has not been included because it is outside the scope of this recipe.

See also

For information about setting and retrieving values in the session, refer to the next two recipes, Adding data to the session and Getting session data.

Adding data to the session

Data that is set in the session is maintained between client requests. For example, we could display announcements at the top of all our pages and include an option to hide the announcements. Once a user opts to hide the announcements, by setting a value in the session, we would be able to ‘remember’ this throughout the user’s visit.

To put this into context, we would set a session value hideAnnouncements to true when a user opts to hide announcements. In subsequent requests, we will be able to retrieve the value of hideAnnouncements from the session and its state will remain the same.

In Joomla!, session data is maintained using a JSession object, which we can retrieve using JFactory. This recipe explains how to set data in the session using this object instead of using the global PHP $_SESSION variable.

Getting ready

We must get the session handler, a JSession object. For more information, refer to the first recipe in this article, Getting the session handler.

$session =& JFactory::getSession();

How to do it…

The JSession::set() method is used to set a value in the session. The first parameter is the name of the value we want to set; the second is the value itself.

$session->set('hideAnnouncements', $value);

The JSession::set() method returns the previous value. If no value was previously set, the return value will be null.

// set the new value and retrieve the old
$oldValue = $session->set('hideAnnouncements', $value);
echo 'Hide Announcement was ' . ($oldValue ? 'true' : 'false');
echo 'Hide Announcement is now ' . ($value ? 'true' : 'false');

Lastly, we can remove data from the session by setting the value to null.

// remove something
$session->set('hideAnnouncements', null);

How it works…

The session contains a namespace-style data structure. Namespaces are required by JSession and by default all values are set in the default namespace. To set a value in a different namespace, we use the optional JSession::set() third parameter.

$session->set('something', $value, 'mynamespace');

Sessions aren’t just restricted to storing basic values such as strings and integers. The JUser object is a case in point—every session includes an instance of JUser that represents the user the session belongs to. If we add objects to the session, we must be careful. All session data is serialized. To successfully unserialize an object, the class must already be known when the session is restored. For example, the JObject class is safe to serialize because it is loaded prior to restoring the session.

$value = new JObject();
$session->set('aJObject', $value);

If we attempt to do this with a class that is not loaded when the session is restored, we will end up with an object of type __PHP_Incomplete_Class. To overcome this, we can serialize the object ourselves.

// serialize the object in the session
$session->set('anObject', serialize($anObject));

To retrieve this, we must unserialize the object after we have loaded the class. If we do not do this, we will end up with a string that looks something like this O:7:”MyClass”:1:{s:1:”x”;s:10:”some value”;}.

// load the class
include_once(JPATH_COMPONENT . DS . 'myclass.php');
// unserialize the object from the session
$value = unserialize($session->get('anObject'));

There’s more…

There is an alternative way of setting data in the session. User state data is also part of the session, but this data allows us to save session data using more complex hierarchical namespaces, for example com_myextension.foo.bar.baz. To access this session data, we use the application object instead of the session handler.

// get the application
$app =& JFactory::getApplication();
// set some data
$app->setUserState('com_myextsion.foo.bar.baz, $value);

An advantage of using user state data is that we can combine this with request data. For more information refer to the next recipe, Getting session data.

The JApplication::setUserState() method is documented as returning the old value. However, a bug prevents this from working; instead the new value is returned.

See also

For information about retrieving values from the session, refer to the next recipe, Getting session data.

Getting session data

Data that is set in the session is maintained between client requests. For example if during one request we set the session value of hideAnnouncements to true, as described in the previous recipe, in subsequent requests we will be able to retrieve the value of hideAnnouncements and its state will remain the same.

In Joomla!, session data is maintained using the global JSession object. This recipe explains how to get data from the session using this object instead of from the normal global PHP $_SESSION variable.

Getting ready

We must get the session handler, a JSession object. For more information, refer to the first recipe in this article, Getting the session handler.

$session =& JFactory::getSession();

How to do it…

We use the JSession::get() method to retrieve data from the session.

$value = $session->get('hideAnnouncements');

If the value we attempt to retrieve is not set in the session, the value null is returned. It is possible to specify a default value, which will be returned in instances where the value is not currently set in the session.

$defaultValue = false;
$value = $session->get('hideAnnouncements', $defaultValue);

How it works…

The session contains a namespace-style data structure. Namespaces are required by JSession and by default all values are retrieved from the default namespace. To get a value from a different namespace, we use the optional third JSession::get() parameter.

$value = $session->get('hideAnnouncements', $defaultValue,
'mynamespace');

It is possible to store objects in the session. However, these require special attention when we extract them from the session. For more information about storing objects in the session, refer to the previous recipe, Adding data to the session.

There’s more…

There is an alternative way of getting data from the session. User state data is also part of the session. The user state data allows us to store session data using more complex hierarchical namespaces, for example com_myextension.foo.bar.baz. To access user state data, we use the application object instead of the session handler.

// get the application (this is the same as $mainframe)
$app =& JFactory::getApplication();
// get some user state data
$value = $app->getUserState('com_myextsion.foo.bar.baz');

User state data is usually combined with request data. For example, if we know the request may include a value that we want to use to update the user state data, we use the JApplication::getUserStateFromRequest() method.

// get some user state data and update from request
$value = $app->getUserStateFromRequest(
'com_myextsion.foo.bar.baz',
'inputName',
$defaultValue,
'INTEGER'
);

The four parameters we provide this method with are the path to the value in the state data, the name of the request input from which we want to update the value, the default value (which is used if there is no value in the request), and the type of value. This method is used extensively for dealing with display state data, such as pagination.

// get global default pagination limit
$defaultListLimit = $app->getCfg('list_limit');
// get limit based on user state data / request data
$limit = $app->getUserStateFromRequest(
'global.list.limit',
'limit',
$defaultListLimit,
'INTEGER'
);

See also

For information about setting values in the session, refer to the previous recipe, Adding data to the session.

LEAVE A REPLY

Please enter your comment!
Please enter your name here