mbeals Posted July 29, 2008 Share Posted July 29, 2008 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. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted July 30, 2008 Share Posted July 30, 2008 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(); ?> Quote Link to comment Share on other sites More sharing options...
mbeals Posted July 30, 2008 Author Share Posted July 30, 2008 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? Quote Link to comment Share on other sites More sharing options...
bretticus Posted August 1, 2008 Share Posted August 1, 2008 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. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted August 1, 2008 Share Posted August 1, 2008 Either way, just remember that resources does not persist so you need to create them again using __wakeup(). Quote Link to comment Share on other sites More sharing options...
Stooney Posted August 2, 2008 Share Posted August 2, 2008 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; } } Quote Link to comment Share on other sites More sharing options...
jchemie Posted August 8, 2008 Share Posted August 8, 2008 Well, If you are serializing, and want this to move across different sessions, you may also consider it storing in a mysql database! you can do a lot with this... just a tip of iceberg . Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.