Part of the EllisLab Network
   
1 of 3
1
flash data
Posted: 01 May 2006 10:02 AM   [ Ignore ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

One very useful feature I’ve seen in other application frameworks is flash data. Nothing to do with macromedia flash… this is data available upon the very next request, and automatically discarded thereafter. This is extremely useful, and quite addictive after you once use it. smile

Example of how it would be used:

// update user profile
$this->profile->update($_POST);
// set flash message:
$this->flash->set('msg','Your profile has been updated');
// redirect
redirect('user/home');

Then the header file of a global layout view:

<?=flash('msg')?>

Anything stored in the flash data would be automatically erased after the next request. The utility of flash data should be obvious… no need to deal with sessions, variable assignments, clearing, etc. This is typically used to display messages prior to a form post, or passing simple information to a form redraw (like a referrer path) without mucking with hidden vars and such. It should also be possible to set a flag to keep the flash data through a second request, in the case of a double redirect.

I’m using my own hack to handle flash vars, but this would be cool to see as an integrated feature of CI.

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 01 May 2006 10:14 AM   [ Ignore ]   [ # 1 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  886
Joined  03-06-2006

Sounds interesting. Where would this data be stored? As a cookie or what?

 Signature 

Corozal, Belize | Linux.bz | Using Kubuntu Linux 7.10 | CodeIgniter 1.5.3

Profile
 
 
Posted: 01 May 2006 10:16 AM   [ Ignore ]   [ # 2 ]  
Administrator
Avatar
RankRankRankRankRankRank
Total Posts:  7337
Joined  03-23-2006

I agree!  This would be a very useful feature.  I’ve been using using sessions, then wiping them on the page… messy, messy.  Flash data would be brilliant!  Sounds like a perfect plugin.  I’ve got a very long todo list, but if I find time I’ll try it.  If anyone writes anything similar, please post back to this thread!

 Signature 

DerekAllard.com - CodeIgniter, ExpressionEngine, and the World of Web Design
BambooInvoice - Open Source, CodeIgniter powered invoicing.

Profile
MSG
 
 
Posted: 01 May 2006 10:36 AM   [ Ignore ]   [ # 3 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006
linuxbz - 01 May 2006 10:14 AM

Sounds interesting. Where would this data be stored? As a cookie or what?

I am using a session. That is a bit of an issue, as sessions may or may not be used in a given application. I suppose a cookie could work too, maybe a useful option?

My library is quite simple actually, I’ll post it here. The trick is to call $this->flash->clear() in the main controller after the request is completed. In PHP5, this is pretty easy with a destructor. PHP4 will require some more craftiness.

application/init/init_flash.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* init_flash
*
* This initializes the flash library
*
* @package flash
* @author  Monte Ohrt
*/

if ( ! class_exists('Flash'))
{
  
require_once(APPPATH.'libraries/flash'.EXT);
}

$obj
=& get_instance();
$obj->flash = new Flash();
$obj->ci_is_loaded[] = 'flash';

?>


application/libraries/flash.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Flash
*
* The Flash library
*
* @package flash
* @author  Monte Ohrt
*/

class Flash {

  
var $keep = false;

   
/**
   * Flash
   *
   * class constructor
   *
   * @access  public
   */
  
function Flash() {}

   
/**
   * set
   *
   * set a flash var
   *
   * @access  public
   * @param   string  $var varname
   * @param   mixed   $val value
   * @return  boolean
   */    
   
function set($var,$val)
    
{
      $_SESSION[
'flash'][$var] = $val;
    
}        

   
/**
   * get
   *
   * get a flash var
   *
   * @access  public
   * @param   string  $var varname
   * @return  boolean
   */    
   
function get($var)
    
{
      
return isset($_SESSION['flash'][$var]) ? $_SESSION['flash'][$var] : null;
    
}        

   
/**
   * clear
   *
   * clear flash vars if $keep is not set
   *
   * @access  public
   * @return  boolean
   */    
   
function clear()
   
{
     
if(!$this->keep)
       unset(
$_SESSION['flash']);
   
}        

   
/**
   * keep
   *
   * keep flash vars one more request
   *
   * @access  public
   * @return  boolean
   */    
   
function keep()
   
{
     $this
->keep = true;
   
}
              
}
?>

flash helper func

/**
* flash
*
* show a flash variable
*
* @access public
* @param  string $var the flash varname
* @return mixed  the flash var value, or null if none available
*/
function flash($var)
{
  $obj
=& get_instance();
  return
$obj->flash->get($var);
}
 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 01 May 2006 11:03 AM   [ Ignore ]   [ # 4 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

I thought of one way to handle this with PHP4. In the class constructor, you can copy the session data to an object property, then unset the session right there. Then a call to $this->flash->get() would get the info from the property instead of the session. If a call to keep() is made, then copy the data back to the session.

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 01 May 2006 11:08 AM   [ Ignore ]   [ # 5 ]  
Research Assistant
RankRankRank
Total Posts:  970
Joined  04-13-2006

This sounds a bit like a Registry pattern to me. But I’m only at the learning stage with Patterns, so don’t shoot me.

Profile
 
 
Posted: 01 May 2006 12:01 PM   [ Ignore ]   [ # 6 ]  
Grad Student
Rank
Total Posts:  65
Joined  03-02-2006

Re: Registry. Kind of.

A Registry is a Singleton that gives you a place to stash something by key and retrieve it later. In most PHP applications, the Registry lives only for the length of the HTTP request and is a good way to avoid dealing with globals.

In the case of the flash parameter, the value lives across HTTP requests, like a session, but the convention for flash parameters is that they live only across a single request. Kind of the opposite of a session store.

A session store: You create the persistent value and it sticks around until you explicitly destroy it (or the session expires).

A flash store: You create the persistent value and it only sticks around until the next request, and is then implicitly destroyed unless you reset it (which would kind of defeat the purpose).

Flash parameters are great little tools to have available. RoR and Symfony both have them.

 Signature 

MSM

Profile
 
 
Posted: 01 May 2006 02:01 PM   [ Ignore ]   [ # 7 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

I have updated the flash library to work with sessions or cookies, and also works with PHP4 or PHP5.  Just drop these files in their place. Use the constant FLASH_CONTAINER to set the container. default is session.

usage

// set the container to session or cookie, must happen before class is (auto)loaded
define('FLASH_CONTAINER','cookie');
// load library (or use autoload)
$this->load->library('flash');
// set a flash message
$this->flash->set('msg','profile updated');
// make current messages persist one more request
$this->flash->keep();
// get flash var
$this->flash->get('msg');

// display a flash var in a view file
<?=flash('msg')?>

applications/init/init_flash.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* init_flash
*
* This initializes the flash library
*
* @package flash
* @author  Monte Ohrt
*/

if ( ! class_exists('Flash'))
{
  
require_once(APPPATH.'libraries/flash'.EXT);
}

$obj
=& get_instance();
$obj->flash = new Flash();
$obj->ci_is_loaded[] = 'flash';

?>

application/libraries/flash.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Flash
*
* The Flash library
*
* @package flash
* @author   Monte Ohrt
*/

class Flash {

  
var $keep = false;
  var
$last_data = array(); // data from last request
  
var $new_data = array();  // new data this request
  
var $container = 'session'; // session or cookie. set with FLASH_CONTAINER constant

   /**
   * Flash
   *
   * class constructor
   *
   * @access  public
   */
  
function Flash()
  
{
    
if(defined('FLASH_CONTAINER'))
      
$this->set_container(FLASH_CONTAINER);

    
// load last request, then remove from session/cookie
    
if($this->container == 'session')
    
{
      $this
->last_data = isset($_SESSION['flash']) ? $_SESSION['flash'] : array();
      unset(
$_SESSION['flash']);
    
}
    
else
    
{
      $this
->last_data = isset($_COOKIE['flash']) ? unserialize($_COOKIE['flash']) : array();
      
setcookie('flash',null,time()-3600,'/');
    
}
  }  
  
  
/**
   * set
   *
   * set a flash var
   *
   * @access  public
   * @param   string  $var varname
   * @param   mixed   $val value
   * @return  boolean
   */    
  
function set($var,$val)
  
{
    $this
->new_data['flash'][$var] = $val;
    if(
$this->container == 'session')
    
{
      
if($this->keep)
        
$_SESSION['flash'] = array_merge($this->last_data,$this->new_data);
      else
        
$_SESSION['flash'] = $this->new_data;
    
}
    
else
    
{
      
if($this->keep)
        
setcookie('flash',serialize(array_merge($this->last_data,$this->new_data)),null,'/');
      else
        
setcookie('flash',serialize($this->new_data),null,'/');
    
}
    
  }        

  
/**
   * get
   *
   * get a flash var from last request
   *
   * @access  public
   * @param   string  $var varname
   * @return  boolean
   */    
  
function get($var=null)
  
{
    
return isset($this->last_data['flash'][$var]) ? $this->last_data['flash'][$var] : null;
  
}        

  
/**
   * keep
   *
   * keep flash vars one more request
   *
   * @access  public
   * @return  boolean
   */    
  
function keep()
  
{
    $this
->keep = true;
    if(
$this->container == 'session')
      
$_SESSION['flash'] = array_merge($this->last_data, $this->new_data);
    else
      
setcookie('flash',serialize(array_merge($this->last_data, $this->new_data)),null,'/');
  
}

}
?>

flash helper

/**
* flash
*
* show a flash variable
*
* @access  public
* @param   string $var the flash varname
* @return  mixed  the flash var value, or null if none available
*/  
function flash($var)
{
  $obj
=& get_instance();
  return
$obj->flash->get($var);
}
 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 01 May 2006 02:08 PM   [ Ignore ]   [ # 8 ]  
Grad Student
Rank
Total Posts:  74
Joined  03-22-2006

I really don’t see why this kind of class would be nice.
PROs:
1. simple way to store CERTAIN info into the $_SESSION
CONs:
1. 2 more files to be read from the disc
Maybe if there would be more to it but I think that improving the Session library to store data only SERVER-SIDE besides CLIENT-SIDE would be more helpfull.
What’s wrong with?

//set flash message
$SESS->set_userdata("message_login_success", "Whatever message you want");
//get flash mesage
$SESS->get_userdata("message_login_success");
//delete flash message
$SESS->clear("message_login_success");
Profile
 
 
Posted: 01 May 2006 02:16 PM   [ Ignore ]   [ # 9 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

The biggest advantage to flash vars is the automation. At any point in your code, you can set a flash variable and then promptly forget about it. No matter where you go from there, as long as the view layout checks for the flash message, it will get displayed once and automatically removed.

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 01 May 2006 04:21 PM   [ Ignore ]   [ # 10 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  130
Joined  04-14-2006

I’ve also re-implemented this in mohrt’s phpsession library. See http://codeigniter.com/forums/viewthread/44945/#k3

 Signature 

CIForge.com - CodeIgniter Community Source Hosting

Profile
 
 
Posted: 02 May 2006 12:22 AM   [ Ignore ]   [ # 11 ]  
Grad Student
Rank
Total Posts:  74
Joined  03-22-2006
mohrt - 01 May 2006 02:16 PM

The biggest advantage to flash vars is the automation. At any point in your code, you can set a flash variable and then promptly forget about it. No matter where you go from there, as long as the view layout checks for the flash message, it will get displayed once and automatically removed.

To automate this I think all you need are some helpers (you know, to help you with stuff smile )

function flash_get($name, $startTag = '<div class="flash-message">', $endTag = '</div>', $keep = FALSE)
{
if (isset($_SESSION[$name])) //you can use the CI phpsession class or whatever you want here
    
echo $startTag.$_SESSION[$name].$endTag;
if (!
$keep)
    unset(
$_SESSION[$name])
}
Profile
 
 
Posted: 02 May 2006 08:05 AM   [ Ignore ]   [ # 12 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  208
Joined  04-18-2006

Problem with that is it will only erase the flash message upon a call to flash_get(), which may not be desirable. The presentation of the message and the erasing should be a separate process.

 Signature 

http://www.motortopia.com/
http://www.huskerlocker.com/
http://www.phpinsider.com/

Profile
 
 
Posted: 02 May 2006 09:01 AM   [ Ignore ]   [ # 13 ]  
Grad Student
Rank
Total Posts:  65
Joined  03-02-2006
mohrt - 02 May 2006 08:05 AM

Problem with that is it will only erase the flash message upon a call to flash_get(), which may not be desirable. The presentation of the message and the erasing should be a separate process.

Exactly. Flash values are usually (at least as I’ve ever seen them) advisory information. The producer of the flash value doesn’t really care if the consumer of the flash value uses it.

 Signature 

MSM

Profile
 
 
Posted: 02 May 2006 09:13 AM   [ Ignore ]   [ # 14 ]  
Grad Student
Rank
Total Posts:  74
Joined  03-22-2006
mohrt - 01 May 2006 02:16 PM

The biggest advantage to flash vars is the automation. At any point in your code, you can set a flash variable and then promptly forget about it. No matter where you go from there, as long as the view layout checks for the flash message, it will get displayed once and automatically removed.

What from what you said here is not done by the code I wrote?
Usually you really need to store flash messages until the first display, so by default you delete the value after the first display. And if the Session library would be able to handle php sessions than you would only need one helper function like I wrote.
You can create 3 helpers functions (to get, set, delete) if you really want. You really don’t need to load 2 files (init_flash and flash) for something that it is so simple.
Probably it’s me but I get headaches when I see dozens of files in each folder of a framework that contains a class for every little mundane operation.
That’s what I liked at CI in the first place smile

Profile
 
 
Posted: 02 May 2006 09:18 AM   [ Ignore ]   [ # 15 ]  
Grad Student
Rank
Total Posts:  74
Joined  03-22-2006
MSM - 02 May 2006 09:01 AM

Exactly. Flash values are usually (at least as I’ve ever seen them) advisory information. The producer of the flash value doesn’t really care if the consumer of the flash value uses it.

What’s the big difference between a flash value and a session value that would require you build a special class to handle it? Also, another issue is that in the view you need to have as little OOP as possible (at least that’s what I understand from the creators of CI) and that’s what a helper is for. So for a project where the HTML is handled by a designer you would still need to create a helper function.

Profile
 
 
   
1 of 3
1
 
‹‹ Data objects and validation      FTP Class ››
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 819, on March 11, 2010 11:15 AM
Total Registered Members: 120468 Total Logged-in Users: 35
Total Topics: 126547 Total Anonymous Users: 5
Total Replies: 665392 Total Guests: 300
Total Posts: 791939    
Members ( View Memberlist )