Jump to content

persisting objects with sessions


mbeals

Recommended Posts

I've figured out that you can persist an object with sessions by serializing the object to a session variable on page close and then checking for and unserializing it on page load.  Very cool stuff, but I'm wondering about the benifits.

 

Take this example:

 

I have an object that builds an html form.  It has two text boxes and a select box to change the type of input box (password, hidden or text).  When you change the type, it reloads the page to reflect the change.

 

Here's the class structure.  Ignore the select class.  It's not really part of the example, I'm just too lazy to write a dynamic select now that I wrote that class.

<?php
class Form{

protected $box1;
protected $box2;
protected $type;
protected $formAction;

function __construct($stuff = NULL){
	if($stuff) $this->fill($stuff);
}

function fill($stuff){
	foreach($stuff as $key => $value){
		if(array_key_exists($key,get_object_vars($this))) $this->$key = $value;
	}
}

function updateFromPost(){
	$this->fill($_POST);
	if($_POST['Submit']) echo "Box1 = {$this->box1}  Box2 = {$this->box2}<br>";
}


function getHTML(){


	$sel = new select;
	$options = array('password' => 'password', 'text' => 'text', 'hidden' => 'hidden');
	$sel->addOption($options);
	$sel->name('type');
	$sel->setSelected($this->type);
	$sel->setArgs(array("onchange" => "this.form.submit();"));

	$html = "<form action='{$this->formAction}' method='POST'>\n";
	$html .= $sel->getHTML();
	$html .= "<input name='box1' type='{$this->type}' value='{$this->box1}'/>\n";
	$html .= "<input name='box2' type='{$this->type}' value='{$this->box2}'/>\n";

	$html .= "<input name='Submit' type='submit' value='submit'>";
	$html .= '</form>';

	return $html;
}

function printHTML(){
	echo $this->getHTML();
}
}

############################
class select {

protected $options;
protected $selected;
protected $name;
protected $args = array();

function __construct($stuff = NULL){
	if($stuff){
		foreach($stuff as $option){
		$this->addOption($option);
		}
	}
}

function addOption($option, $value = NULL){
	if(is_array($option)){
		$this->options = $option;
	}else{
		$this->options[$option] = $value;
	}

}

function setArgs($option, $value = NULL){
	if(is_array($option)){
		$this->args = $option;
	}else{
		$this->args[$option] = $value;
	}
}


function setSelected($val){
	$this->selected = $val;
}

function name($val){
	$this->name = $val;
}


function getHTML(){
	$html = "<select name={$this->name}";
	foreach($this->args as $option=>$value) $html .= " $option='$value'";		
	$html .= ">\n";

	foreach($this->options as $option=>$value){
		$html .= "\t<option value='$value' ";
		if($this->selected == $value) $html .= 'selected="selected"';
		$html .= " >$option</option>\n";
	}
	$html .= "</select>\n";
	return $html;	
}

function printHTML(){
	echo $this->getHTML();
}

}



?>

 

Now the two ways to do it.  Option one is to serialize the object into a session variable:

 

<?php
session_start();
if($_SESSION['object']){

$test = unserialize($_SESSION['object']);
$test->updateFromPost();
$_SESSION['object'] = serialize($test);
}else{

$test = new Form;
$data = array('box1' => 'test1',
			  'box2' => 'test2',
			  'type' => 'text');
$_SESSION['object'] = serialize($test);
$test->fill($data);				  
}

$test->printHTML();
?>

 

If the object is cached in the session variable, it is reinstated and update with new form information, then recached.  If this is the first time creating the object (no cache), a new instance is created and cached.

 

Option 2:  just create a new object every time

 

<?php
if($_POST){

$test = new Form;
$test->updateFromPost();

}else{

$test = new Form;
$data = array('box1' => 'test1',
			  'box2' => 'test2',
			  'type' => 'text');
$_SESSION['object'] = serialize($test);
$test->fill($data);				  
}		


	  
$test->printHTML();
?>

 

This does the same thing as option 1, but relies on POST to contain all the attributes of the old object, which in this case works.

 

Now it seems to me that option 1 would be a lot more flexible, as I'm maintaining the structure of my data from page to page and don't have to worry about reconstructing stuff from the post variable.  It's also very clean and scalable.  Since the only thing that is really going back to the server is the POST variable, bandwidth usage should be about the same.

 

However, is there a performance hit for caching an object in a session variable?  I can't see it happening on an object this small, but what about for larger ones?  Is there any reason not to do this that I'm not seeing, because I really like the potential.

 

Link to comment
Share on other sites

There is no need to serialize/unserialize. Just use a session variable to hold the instance of the class. The only requirement (like it states in the php manual about doing this) is that the class definition must be present before the session start -

 

<?php
// create the object on one page
include('your_class_definition.php');
session_start();
$_SESSION['object'] = new Form;
....
$_SESSION['object']->fill($data);
?>

 

<?php
// restore and access the object on another page
include('your_class_definition.php');
session_start();
....
$_SESSION['object']->printHTML();
?>

Link to comment
Share on other sites

thanks for the shortcut, but I was mostly asking about the performance aspects.

 

Given the two options (persisting the object or repopulating), which is 'faster'.  In the absence of database queries, is it more costly to rebuild an object or just pull the object out of the session variable?

Link to comment
Share on other sites

Given the two options (persisting the object or repopulating), which is 'faster'.  In the absence of database queries, is it more costly to rebuild an object or just pull the object out of the session variable?

 

Session data is just basically serialized automatically to a flat file. Which means the session mechanism has to unserialize the object (and it's state apparently) before rebuilding the object. In other words, you're rebuilding the object either way.

Link to comment
Share on other sites

These are two methods in my session class I use for objects.  I have serialize/unserialize in there, but after reading what PFMaBiSmAd said, that'll probably get removed.

 

public function add_object($id, $object){
	$_SESSION[$id]=serialize($object);
}

public function get_object($id){
	if(array_key_exists($id, $_SESSION)){
		return unserialize($_SESSION[$id]);
	}
	else{
		return false;
	}
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.