POST data not clearing


#1

I am writing my code procedurally and I am experiencing an odd result.

After I add a record to my website, if I click refresh, or CRTL and refresh, then another instance of the same record will be added.

I have sourced this out to a variable which I am setting in a form, but I’m not sure why it is not clearing on a refresh. As part of my debugging, I tried to clear the variable at multiple stages in the code, but nothing is working – when I refresh the page, the variable is being reset to “y”.

Here are the elements of my code.

In my variable declaration section at the top of my page I have:

    $switch_new = $_POST['switch_new'];

Then after the variables section, I have a section for checking if any conditions are met and if so, then a query is run:

if ($switch_new == "y") {
            $sql = "INSERT INTO tableMinis (mini_name, mini_sets_id) values (:miniName, :miniSetsId);";
            $stmt = $pdo->prepare($sql);
            $stmt->execute(['miniName' => addslashes($add_newName), 'miniSetsId' => $setSelection]);
            $stmt = null;
            
            $_POST["switch_new"] = null;
            $switch_new = null; 
}

And here is the form that starts it all off (note: I have omitted the input entries on the form for this example):

echo '<form enctype="multipart/form-data" name="add_newData" id="add_newData" action="main-minis.php" method="post">';
     echo '<input type="hidden" name="switch_new" value="y">';
     echo '<input type="submit" value="Add Mini">';
echo '</form>';

Can someone please offer me some suggestions on how I can prevent this from happening. Thank you.


#2

If you submit a form and then refresh the page on the page that is handling the submission your borwser will run the same request again, including the form submission. An easy fix is to redirect in your php code so you change the request from post with form to a regular get again


#3

Thank you for clarifying that for me. I’m not too familiar with php redirects, so would this be the solution to my problem?

if ($switch_new == "y") {
       $sql = "INSERT INTO tableMinis (mini_name, mini_sets_id) values (:miniName, :miniSetsId);";
       $stmt = $pdo->prepare($sql);
       $stmt->execute(['miniName' => addslashes($add_newName), 'miniSetsId' => $setSelection]);
       $stmt = null;
           
       header("Location: main-minis.php");
}

#4

What @JimL is talking about is known as PRG (Post, Redirect, Get) and is the correct way to solve your problem.

You need to kill the script after a header redirect.


#5

Thanks for the PRG info. Lacking a computer science background, I can generally follow along with the topics, but lacking examples to look at I really don’t know what in my code has to change. I read through this which was quite informative, but I only have baseline understanding of it all:

As far as I can tell, my code changes then should be:

This $switch_new = $_POST[‘switch_new’]; should change to this $switch_new = $_GET[‘switch_new’];

And after the redirect I posted, I should have exit; after it? (This is what the PHP manual indicates). This part I am also a little confused by, because other sources recommend using exit(); or die(); – Which would be the best practice to use?


#6

You handled it with the header redirect. Now just throw in a die right after it otherwise the script will continue to run to the end. Die is the same as exit, just shorter to spell.


#7

Great. Thanks for your help Jim and Benanamen. I got it working now.


#8

Why are you using addslashes at all?


#9

Because some of the data in this name field has periods and apostrophes which were causing all sorts of havoc when the $sql statement was executed.

Is there a better way to accomplish this?


#10

Havoc where? An INSERT should work no problem without it since you are using Prepared Statements. What EXACTLY does “havoc” mean?


#11

That may have been the case when you were putting the variables holding the data directly into the sql query statement, but not now. One of the points of using prepared queries is it protects against any sql special characters in the data from breaking the sql query syntax (which is how sql injection is accomplished.) With prepared queries, you no longer need to do any type of escaping of data in your code, and in fact doing so is added the escape character into the database which will make searching for values difficult.


#12

I was getting errors, however that was before I was using prepared statements. I wasn’t aware that ‘addslashes’ is not needed with prepared statements.

I just ran some tests now without it – and all is working fine. Thanks for letting me know about this.


#13

What you will need to do though is run your HTML output through htmlspecialchars

Example:
echo htmlspecialchars($row['first_name'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

Optimally, you would want to create a helper function for it.

function html_escape($unsafe_data, $encoding)
{
    return htmlspecialchars($unsafe_data, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, $encoding);
}

echo html_escape($unsafe_input, 'UTF-8');