PHP Session Changes in Sugar 7.7

Below is some details from Andreas Sandberg, Director of Engineering, at SugarCRM.  Andreas is on his second tour of duty at SugarCRM.  He first joined SugarCRM back in 2007 as an Engineering manager.  He was also the Head of Engineering at Stitch prior to their acquisition by SugarCRM.

Below he shares some information about some changes that have gone into Sugar 7.7 that change how PHP sessions are stored and the underlying implementation.  Sugar Developers need to be aware of these changes so that their interactions with $_SESSION variable do not yield any unpredicted results.

What has changed with $_SESSION?

We have refactored PHP Session storage so that it is more configurable and allow more control over PHP session handling.  We have introduced a new SessionStorage class at src/Session/SessionStorage.php which extends from the TrackableArray class at src/Util/Arrays/TrackableArray/TrackableArray.php. This means that the $_SESSION variable is now an object instance of a TrackableArray which implements the ArrayAccess interface. This means that most code that treated $_SESSION like an array will continue to work as before.

However, there are three changes that Sugar Developers need to be aware of when working with the PHP session objects.  Each change is outlined below. Two of them are API level changes and the last is really just an adherence to best practices but may yield unexpected results if ignored.

Session Array Functions

In Sugar 7.7, certain array functions will now throw fatal errors when used on the $_SESSION variable.  PHP's native array functions are not safe to use against ArrayAccess objects.  To proactively catch these issues, we have added a health check script to Sugar 7.7 upgrader.  This will warn about use of standard PHP array functions against the $_SESSION variable.



We have modified all areas in the core Sugar 7.7 codebase where this would be problem and have introduced new array utility functions that must be used instead of the standard PHP array functions.

These functions can be found in: src/Util/Arrays/ArrayFunctions/ArrayFunctions.php

These Sugar Functions are safe to use with native PHP Arrays and PHP ArrayAccess implementors such as Sugar's Session object.
Sugar Function
PHP Equivalent
is_array_access
is_array
in_array_access
in_array
array_access_keys
array_keys
array_access_merge
array_merge

(Pre|post)(Increment|Decrement) Operators

With the new implementation, pre and post increment or decrement operators will not work as expected and therefore should be avoided.

For example instead of doing something like:BAD 

$_SESSION['userStats']['pages']++;

Sugar Developers should instead use:GOOD

$_SESSION['userStats']['pages'] += 1;

Assigning unset session references to a variable

There are some improper programming practices that can cause problems. Specifically, when trying to access a session value by key that does not exist.  When that happens, an unexpected value will be assigned.

For example:BAD

//No session value for key authenticateduser_language exists in this example
$GLOBALS['current_language'] = $SESSION['authenticateduser_language'];

In this example our friend the TrackableArray will be assigned to the GLOBAL array instead of a string.

To ensure this never happens always proactively guard against possible null values:GOOD

$GLOBALS['current_language'] = !empty($_SESSION['authenticated_user_language']) ? $_SESSION['authenticated_user_language'] : $GLOBALS['sugar_config']['default_language'];

Returning a session value that is an array

You can prevent unexpected behavior when you expect a session value to be an array by using array type casting.  This will ensure that an array is always returned.BAD

return $_SESSION['reports_getACLAllowedModules'];
GOOD
return (array) $_SESSION['reports_getACLAllowedModules'];