A neat feature which I found in CakePHP was the ability to set a flash
message, say on some save
script, then have that message displayed on the following page. Something like, Post updated
, or Error - no file found.
The way Cake does it is with this session
object. I am trying to avoid sessions like the plague because of their odd requirements for scalability. Can开发者_如何学C I not just simply store the flash message in a cookie (client side) and then delete that cookie once it's displayed on the following page? What would be some pros/cons to this approach - or more simply, why does Cake uses session
(I'm assuming that relates to the _SESSION
collection).
Cheers!
p.s. In my implementation I also make it fade out with a setTimeout
command in javascript. I find that's a nice way to end the whole process.
The problem with a cookie is that the user may disable this functionality. If so, your flash message won't be showed. CakePHP try to be general enough and uses session storage.
You have 3 options:
- Session: the most used approach. It will work in any client computer but, as you say, it could give problems with some server configurations.
- Cookies: it's a good option in general, but the user may block this mechanism. Only recommendable when the your app requirements include the need of cookies.
- Data base: the universal solution. The problem is that it requieres an access to the database (slow). An ID should be passed with the URL (GET method) so the application knows which database register corresponds to this access.
In my applications I use a combination of the 2nd and 3rd approaches: I test for cookies and if they are available, I use them. If not, I use database access, BUT I always cache the DB access in order to not query more than once for each message.
I don't see why you can't use a cookie with an expiration of say 10 minutes from creation date. Downside if the user walks away and comes back in 11 minutes they might not see the flash cookie message...but you won't have to worry about flooding a client with cookies.
Just make some simple content rules to ensure that no privileged information is put into a flash message and you should be good.
A simple implementation could be something procedural like:
function setFlash($id ,$message){
setcookie("flash_{$id}", $message, time() + 60 * 10);
}
function getFlashes(){
$flashes = array();
foreach($_COOKIE as $id => $value){
if(strpos($id, "flash_") === 0){
$flashes[$id] = $value;
//clear flash and set expiration to 10 minutes in past
setcookie($id, "", time() * 60 * -10);
}
}
return $flashes;
//Input cleansing not included for brevity/clarity
}
Alternatively if the flash is originating soley from the client side, you can use something like https://github.com/marcuswestin/store.js to try and use localSession store to manage flash messages.
Another idea is the transport of the message via the hash in the url:
if (isset($_POST['submit'])) {
...
header("Location: ".$_SERVER["REQUEST_URI"]."#".urlencode($msg));
...
}
Advantages:
- Does work without cookies / sessions / databases / memcaches etc. :-)
- Does not rely on client clock as cookies do
- No other client request can "steal" the message
Disadvantage:
- looks ugly
- Maximum safe url length 2000 characters (see What is the maximum length of a URL in different browsers?)
- needs client side JavaScript to read and display the hash value
- if bookmarked: message gets displayed everytime again
Sessions are unfortunately not always reliable when followed by Header("Location ...");
I was thinking of putting it to GET request or Hash tag as was suggested, and you can erase it on next page using javascript from the URL using window.history.pushState.
Edit: Unless session_write_closed(); is used.
精彩评论