PHP Form Validation 'success' message on results listings page

Hi there,

After adding / editing an entry on my database, I’d like a “success” message to appear on the results page.

Is there some PHP code that can check the condition of whether the previous action performed was adding / editing an entry on the database? (Obviously the results page should only display the message if this is the case but not at any other time).

In my PHP index the ‘add’ and ‘edit’ code both end with the “header(‘Location: .’);” function so that it runs back through the index to the code that compiles data and redirects to the results page. If you ‘include’ the results page at the end of the add/edit code, it causes undesired multiple submissions of the new entry each time you refresh the results page.

I’ve got a feeling I might need to use ‘sessions’, which I’ve yet to get to grips with…

Any ideas gratefully received (but let me know if you need more info in the meantime),

Cheers,

Andy


function success($success = false){
      if($success == true){
            // show your message
      }
       

      return false;

}

Sorry, could you expand on this please. I’m guessing this function would be used as an include but I can’t see quite how it would tell whether data has been added to / edited in the database and then be able to use that information as a conditional factor. And I can’t see that this is a built-in function either.

Thanks.

I do it with a session variable. If you don’t use sessions yet then it’s as easy as calling session_start() in most (or all) of your pages. Then just after inserting data into the database do something like this:


$_SESSION['message'] = 'Data added successfully';

And on the subsequent page read the value once, display it and delete so that it won’t appear again:


if (isset($_SESSION['message'])) {
  echo $_SESSION['message'];
  unset($_SESSION['message']);
}

I often use this approach (in a more elaborate way) and it works well. I run the code above on every page so that I don’t have to remember about it and just store the message into the session whenever I need to display it to the user.

Great - thanks so much. I thought that may be the case and found another site which also advised this course of action.

Sorry, I know I’m being immensely thick, but what would be the correct command to display the SESSION variable statement?

I enter this directly after the insertion of data into the database via the form (I assume I only need to use the “session_start()” function here and not again after redirecting to the next page?):

session_start();
$_SESSION['message'] = 'Data added successfully';
header('Location: .');
exit();

Then this after it has been redirected to the last part of the index:

if (isset($_SESSION['message']))
{ 
echo $_SESSION['message']; 
unset($_SESSION['message']); 
}
$pagetitle = 'Results';
include 'results.html.php'; //RETURNS TO RESULTS PAGE
?>

And this is how I am attempting to display it on the results page:

<?php echo ($_SESSION['message']); ?>

But am getting this error message (referring to where I am trying to display it):

Notice: Undefined variable: _SESSION

I’ve tried a good few things now and just can’t seem to get it to work. I realise I am echoing it twice (in the index and on the actual results page) and that I will therefore likely need to change the “echo” statement set just before the session is unset, but I’m not sure what I’d need to change it to.

Thanks!

You need to execute session_start() on every page that wants to use the $_SESSION variable.

Ah, knew I was being idiotic - thanks!

I have got it working if I use the below snippet of PHP directly on the results page - is this the best way?

Or is there a way of doing it using the code in the index (and keeping the whole start/if/unset session protocol there) so that you only need to output the one variable on the results page?

I’d imagine you’d just need to use a slightly different command in place of echo, just to re-state what the variable is after checking the session is open, so that it can then be echoed out on the results page, but I can’t figure out what that would be.

session_start();
if (isset($_SESSION['message']))
{ 
echo $_SESSION['message']; 
unset($_SESSION['message']); 
}

Cheers!

It all depends on how you structure your code. When I create a php application I always execute all page requests through a single index.php and keep my html in separate files - templates. This keeps most of my code clean. I start the session and read the message in index.php so it is done on every page, I pass the message to the template. Then the template just checks if there is any message passed and displays it if necessary. In a simplest way it would look like this:


session_start();
// initialize template object
$tpl = new Template();
if (isset($_SESSION['message']))
{
  // pass the message to the template
  $tpl->assign('message', $_SESSION['message']);
  unset($_SESSION['message']);
}

// decide what template to display based on the URL, for example results.tpl
$tpl->setTemplate($_GET['page'] . ".tpl");

// perform various necessary tasks on this page which are performed in their own php files
include $_GET['page']. ".php";

// display the template
$tpl->display();

And then results.tpl:


<html>
<head>
  <title>Results</title>
</head>
<body>
<? if(isset($message): ?>
  <div class="message"><?=$message ?></div>
<? endif; ?>

<p>Some other page elements...</p>
</body>
</html>

This is a very simplified example, don’t use this code as it is insecure where it uses $_GET directly in include. Even if you don’t use any template engine and only use includes it is good idea to use a separate file for html - or at least split the php file into two parts - the first one does any php logic that is necessary and the second displays the page.

If you don’t use a single index.php then you can put all the code that has to be executed on each page into a separate file and include it in every php page that is executed.

These are only ideas - how you structure your code is up to you but try to keep it organized as it will be helpful in the future :slight_smile:

Cool, thanks.

If you don’t want to use session variable then you can use

$msg = ‘Data edited successfully’;
header(“Location: index.php?msg=$msg”);
exit();

and your listing index.php page you can use

if(isset($_REQUEST[‘msg’]) && $_REQUEST[‘msg’] != NULL){
echo $_REQUEST[‘msg’];
}

and if you don’t want both query string msg message or session variables then post the successfully message using curl post method. There are so many options there. Ajax can be also used.

I wouldn’t put the actual message in the GET or POST variables. Both can be modified by the user, and displaying any unfiltered user input on your page is dangerous. At the very least, it leaves your page vulnerable to XSS attacks. What happens when a user goes to index.php?msg=some malicious javascript code hijacking cookies or something? An attacker could mass email people a link to your page with msg=whatever and do all kinds of nasty things.

If you want to use the GET or POST variables to display error messages, think of something like this instead:


<?php

if ((isset($_GET['msg'])) && ($_GET['msg'] != null))
{
    switch $_GET['msg']
    {
        case '1':
            echo "This is message #1";
            break;
        case '2':
            echo "This is message #2";
            break;
        case '3':
            echo "This is message #3";
            break;
    }
}

?>

Good point about not putting msg directly into the url. But I also think that msg shouldn’t be put into the url even if it is encoded into 1, 2, 3 as shown above. My reasoning is that a url is an address that should point to a certain content - and the message actually is not the content of the page, it’s just a temporary message that says what action has just been performed for the user and it doesn’t really belong to the content of the page at the given url. Url’s can be bookmarked, can be sent to others via email, can be put on other web pages, etc. - and if a user bookmarks a url which ends with ?msg=1 then every time he visits this bookmark he will see the message displayed while of course the message is about something that occurred long ago and is not relevant to this visit and describes something which is not true and can be confusing. Therefore, I believe it’s best to use sessions for this purpose whenever possible.

At worst, if I really could not use a session for some reason I would encode the message behind some random generated key that would expire as soon as the message has been displayed. The message would be stored on the server in a database or even plain text file. For example, the script that has just made some change in the database creates a file with a random name 028f9faab6c5100b4bf37818b2.txt and with a content ‘Data added successfully’. Then the user is redirected to the next page with the url ending with ?msg=028f9faab6c5100b4bf37818b2. The script on the next page reads the message from the file and deletes the file. So if someone bookmarks this page then despite the ?msg= parameter present he will not see the message any more, which is good.

Yeah, I agree with you. I prefer to use sessions as well and don’t really think that things like messages/notices should be in the GET variable. I just wanted to make sure he was aware of some of the security implications involved with the method blogaddition suggested.

Thanks for all this guys. The book I’m learning from is pretty thorough about avoiding putting sensitive material in the GET and POST variables, so I’ve opted just to check/echo/end a session using a snippet of PHP within my results page, which seems to be the simplest thing and keeps a clean, safe URL.

Ideally I like to keep all the PHP code in a separate index file, but having just this one piece can’t hurt.

Thanks again,

Andy

I’m having a few problems sending a variable via a session.

Index:

session_start();
$_SESSION['message'] = 'THIS ATTRACTION HAS BEEN EDITED:' . ' ' . $attraction_name;
header('Location: .');
exit();

Display page:

<?php session_start();	if (isset($_SESSION['message'])) { echo $_SESSION['message']; unset($_SESSION['message']); } ?>

Using the above, if the attraction ‘St. Paul’s Cathedral’ ($attraction_name) was used (having first been sanitized with mysqli_real_escape_string for entry into the database), the echoed output via the session would be:

'THIS ATTRACTION HAS BEEN EDITED: St. Paul\‘s Cathedral’.

Obviously it is not being converted by htmlspecialchars (hence the backslash) but I can’t figure out where I can use that function. I’ve tried using it in various places and even tried creating a variable to be used specifically for the session (all to no avail) i.e.:

$attraction_name_session_output = htmlspecialchars($attraction_name, ENT_QUOTES, 'UTF-8');

It also obviously works if I use the below, but I would have thought that poses a security risk given user-generated content is being run through a session? Or should I not worry given this is not entered into the database?:-

$_SESSION['message'] = 'THIS ATTRACTION HAS BEEN EDITED:' . ' ' . $_POST['attraction_name'];

Any ideas? Thanks!

Sorry, of COURSE it needs to be output as a variable converted via htmlspecialchars rather than $_POST[‘attraction_name’], so ignore the last suggestion of the above.

I now realise it’s something to do with magic quotes but have the appropriate code included at top of my controller so not quite sure what is causing the problem…