PHP Sessions in a Load Balanced Environment

One thing that we struggle with in our server environment as many others do is doing load balancing and being able to sync session data between all the machines. Having one dedicated session space or server can be an option but that can get a little messy or expensive. So we added MySQL Sessions to the Simpl framework and it is easy as pie to use.

Originally adopted from Joseph Crawford but implemented completely in Simpl. Josephs was great except it seemed to be connected to a larger whole. The bits and pieces were there for the session but they just needed to be combined with a framework. Below is a fully featured example working and usable.

Prerequisits:

  • PHPSimpl
  • MySQL Database Connection
  • “session” Table
    CREATE TABLE `session` (
    `ses_id` varchar(32) NOT NULL,
    `last_access` int(12) unsigned NOT NULL,
    `ses_start` int(12) unsigned NOT NULL,
    `ses_value` text NOT NULL,
    PRIMARY KEY (`ses_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Used to store the sessions data';

Usage Steps:

  1. Download and copy Simpl to the web server.
  2. Define some base items
    // Directories
    // Always Include trailing slash "/" in Direcories
    define('DIR_ABS', '/usr/local/www/');
    define('FS_SIMPL', DIR_ABS . 'simpl/');
    define('FS_CACHE', DIR_ABS . 'cache/');// Enable Database Sessions
    define('DB_SESSIONS', true);// Database Connection Options
    define('DB_USER', 'username');
    define('DB_HOST', 'localhost');
    define('DB_PASS', 'password');
    define('DB_DEFAULT', 'site_data');
  3. Include the framework
    // Simpl Framework
    include_once(FS_SIMPL . 'simpl.php');
  4. Connect to the database
    // Make the DB Connection
    $db = new DB;
    $db->Connect();
  5. Use the $_SESSION super global just as you normally would and PHPSimpl does all the work for you.

The only modification may be the page cannot close the database connection since the _SESSION variable has to be written after the page is completely loaded and thus must still have the connection available.

Simpl and the $db object to all the hard work of redirecting the session data and pulling it from the database. No need to call a session_start() or even interact with the session table.

If you are interested in what the Session class looks like here is the source code:
Session.php

PHPSimpl API Documentation

So we started to document the PHPSimpl API, which is quite a large task since we did not start the documentation process till the API was almost complete. Although PHPSimpl has almost full JavaDoc documentation throughout the source it is a pain to open up the source every time you need to look up the parameters to a function call. So we started to document all the classes, functions, examples of their use and return values at the projects homepage wiki. Most of the classes are in there now and more will be added shortly. If you would like to contribute to the documentation effort just let me know and I can add you to the list.

Wiki:http://code.google.com/p/phpsimpl/w/list

Base Classes:http://code.google.com/p/phpsimpl/wiki/BaseClasses

New PHPSimpl caching system

It has been a little bit but a few things have happened in the past month or so. We implemented a new caching system that will speed up the saving and retrieving of table cache to the filesystem. There is no change in the API, the only thing that you will notice is that the cache now has a “table_*.cache.php” naming format. This was changed to distinguish it from the other caches that have been implemented in the past month.

The other caching that has been implemented is the query cache. This is a simple system that is enabled by a boolean define named “QUERY_CACHE”, if it is set to true every time a “SELECT” query comes through $qb->Query() it saves its results to a file. So next time the same query comes around there is no need to re-query the database for the same information it is already available in the cache. This query will stay in cache till $db->Perform() is called which at that time all the query caches are cleared out. We have found this is a significant increase in performance for large queries that require a few joins and sorting.

This also brings up the situation where possibly all the queries on the page are found in cache and we got to thinking why even bother connecting to the database unless we really need to. So Simpl now will not connect to the database until the first query comes by that could not be found in cache. We have found that this also improves performance especially if the database is on a separate machine. There is only one downside to this addition, when calling $db->Connect() it will always return true since it just stores the database information and waits for the first query, you will no longer be able to check on connect if the database is available or not, it will always look available.

The last functionality that was added was the deprecation of the “CLEAR_CACHE” define. Currently it is still working for backwards compatibility but will soon be removed. It has been replaced by the use of a GET variable that can be used on any page. There are two that will be able to clear specific caches and one that will clear all the caches.

page.php?clear -> Clears all the caches (table and query)
page.php?clear_query -> Clears just the query cache
page.php?clear_table -> Clears just the table cache

You can call these GET variables on any page that creates the “mySimpl” class and the cache will be cleared.

PHPSimpl Join() jumps into action

Its amazing how much code can be reduced by using a framework, especially a framework that accomplishes all the most basic elements without interfering with usability. With PHPSimpl we are trying to accomplish just that. So we recognized the problem of information being in two different tables and having two queries just was not cutting it. So we are proud to announce the Join() function in DbTemplate. This is now integrated into the examples also to get you up and running with it.

Here is a sample code snipit of joining the Registration, User and Payments tables to view information all in one list with one query:

// Create the Registration class
$myRegistration = new Registration;
$display[] = array('registration_id','user_id','date_registered','guests');// Create the User Class
$tmpUser = new Users;
$myRegistration->Join($tmpUser, 'user_id', 'INNER');
$display[] = array('first_name','last_name');// Create the Payments Class
$tmpPayment = new Payment;
$myRegistration->Join($tmpPayment, 'conference_id', 'INNER');
$display[] = array('conference_id', 'amount', 'status', 'method');// Get a list of all the Registrations
$myRegistration->GetList($display,'date_registered','DESC');

Questions or Concerns? Head over to our PHPSimpl Group.

Just added, Output individual fields

So PHP Simpl does a good job of outputting an XHTML form with very extend able features such as labels, required *’s, size and maxlength calculation, example and error output automatically. But have you ever just wanted to output the form in your own way? Well now you can, this can be accomplished with the FormField() function inside the DbTemplate class. It handles all that same great XHTML formatting, you just have to worry about where you want to flied to be displayed.

Function Prototype:

public function FormField($field, $hidden=false, $options='', $config='');

Example:

$myPost = new Post;
$hidden = false;
$options = array();
$config = array();echo '<form>';
$myPost->FormField('title', $hidden, $options, $config);
echo '<input name="submit" value="Save" type="submit">';
echo '</form>';