CakePHP’s setFlash() compared to Rails flash

CakePHP is a great framework. I love it. It’s simple and you can build applications really fast. Anyway, since I also tried Ruby on Rails there are ceratin things that annoy me. Little things. For example the “flash messages”.

What’s that? Here ’s the rails documentation and here’s the cake documentation. You can use the flash to pass temporary objects between actions/requests. Most of the Time I use it to display notices or error messages like “The Item has been saved” or “Oh oh, you’re not allowed to do that”…

In Rails you can create such a message like this:

def create
  # some code to create/save something
  flash[:notice] = "The item has been saved"
  redirect_to :action => :index
end

In your views ( or your layout) you can use this flash like this:

<%= flash[:notice] %>

You can use other keys than “notice” too:

#controller:
flash[:error] = "Something went horribly wrong"
# view:
<%= flash[:error] %>

It works just fine.

In CakePHP you have to do the following:

function create()
{
  //some code to create / save someting
  $this->Session->setFlash("Saved");
  $this->redirect("somewhere");
}

And in you’re view:

<?php echo $session->flash();?>

Flashs are something I need very often and I think it should be easier to set the flash. (And with easier I mean less keystrokes.)
Well, to be fair: $this->Session->setFlash has some more options and parameters than the rails way. But most of the time I don’t need them. I like how easy it is in rails…

That should be possible for cake too. Here’s how I would like it:
In the controller:

function create()
{
  //some code to create / save someting
  $this->flash["notice"] = "Saved";
  // or if something went wrong:
  $this->flash["error"] = "Oh oh";
  //or use whatever key you like for your flash
  //redirect
}

And in the view:

<?php echo $flash["notice"];?>

Or if you want to style your messages and wrap them with a div:

<?php if($flash["notice"]):?>
  <div class="notice">
    <?php echo $flash["notice"];?>
  </div>
<?php endif;?>

Is this possible? Sure. Here’s a sample Component to achieve exactly this:

<?php 
class FlashHash implements arrayaccess {
    public $now = array();
    public function __construct($key = "flashhash") {
    	$this->key = $key;
 
    	//copy all messages from the session and delete the session...
    	$this->now = isset($_SESSION[$this->key]) ? $_SESSION[$this->key] : array();
    	$_SESSION[$this->key] = array();
    }
 
    // implements the arrayaccess interface
    public function offsetSet($offset, $value) {
        $_SESSION[$this->key][$offset] = $value;
    }
    public function offsetExists($offset) {
        return isset($this->now[$offset]);
    }
    public function offsetUnset($offset) {
        unset($this->now[$offset]);
        unset($_SESSION[$this->key][$offset]);
    }
    public function offsetGet($offset) {
        return isset($this->now[$offset]) ? $this->now[$offset] : null;
    }
}
 
class FlashComponent extends Object{
  function startup(&$controller){
  	$controller->flash = new FlashHash();
  	$controller->set("flash", $controller->flash);
  }
}

Just drop it in your /controllers/components folder as flash.php and add it in your app_controller.php:

var $components = array("Flash");

That’s it. now you can use you’re flashs in a rails way.
You can even use

$this->flash->now["notice"] = "Flash now";

to add a flash that appears instantly instead of after a redirect…

I haven’t used this in production it is just a idea how i think it could work.