There are some notifications that belong to the page that generates them, such as errors in form fields. These are easy to handle. I normally create an array to hold them in HTML format and use a function to display them as HTML list:
<?php
$errors = array();
function print_errors($errors){
if( !empty($errors) ){
echo '<ul><li>' . implode('</li><li>', $errors) . '</ul>';
}
}
# ...
if($foo<=0){
$errors[] = '<label for="foo">Foo</label> is <strong>' . htmlspecialchars($foo) . '</strong> but it must be greater than zero.';
}
if(empty($errors)){
save_stuff();
header('Location: http://example.com/somewhere/else/');
exit;
}
# ...
print_errors($errors);
echo '<form action="" method="post">';
echo '<input type="text" name="foo" value="' . htmlspecialchars($foo) . '" id="foo">';
echo '</form>';
# ...
?>
Then there is the case you describe: after a successful (or impossible) action, the user is redirected somewhere else (e.g., main section page) where he gets an explanation. For short messages, I tend to use a GET variables that hold the messages in plain text:
<?php
if( isset($_GET['error']) ){
echo '<p class="error">' . htmlspecialchars($_GET['error']) . '</p>';
}
if( isset($_GET['message']) ){
echo '<p class="message">' . htmlspecialchars($_GET['message']) . '</p>';
}
?>
This is quite fine for intranets, but it has two drawbacks:
If you have some storage available (files, databases, whatever) you can keep full HTML messages and assign them a random ID:
ID: 4a0a19218e082a343a1b17e5333409af9d98f0f5
Date: 2010-05-25 11:24:30
Type: message
HTML: <a href="/item/25">Item #25</a> was modified successfully.
http://example.com/?msg=4a0a19218e082a343a1b17e5333409af9d98f0f5
Make sure you save the date so you can clean up old data now and then.
My two cents.