Stop data inserting into a database twice

后端 未结 16 1344
再見小時候
再見小時候 2020-12-01 00:33

I was wondering what methods/preventions other programmers use to stop data being entered twice into a MySQL database when a user refreshes on the same page as a form? Obvio

相关标签:
16条回答
  • 2020-12-01 01:00

    Ilya's answer is correct, I just wanted to add a little more than would fit in a comment:

    If resubmission is dangerous (going back and submitting again, reloading the result page [if you haven't taken Ilya's advice], etc.) I use a "nonce" to make sure the form can only go through once.

    On the form page:

    <?php
    @session_start(); // make sure there is a session
    
    // store some random string/number
    $_SESSION['nonce'] = $nonce = md5('salt'.microtime());
    ?>
    // ... snip ...
    <form ... >
    <input type="hidden" name="nonce" value="<?php echo $nonce; ?>" />
    </form>
    

    In the processing page:

    <?php
    if (!empty($_POST)) {
    @session_start();
    
    // check the nonce
    if ($_SESSION['nonce'] != $_POST['nonce']) {
        // some error condition
    } else {
        // clear the session nonce
        $_SESSION['nonce'] = null;
    }
    
    // continue processing
    

    After the form has been submitted once, it cannot be submitted again, unless the user intentionally fills it out a second time.

    0 讨论(0)
  • 2020-12-01 01:01

    I call this a golden rule of web programming:

    Never ever respond with a body to a POST-request. Always do the work, and then respond with a Location: header to redirect to the updated page so that browser requests it with GET.

    This way, refreshing will not do you any harm.

    Also, regarding a discussion here in comments. To protect from double posting from, say, accidental doubleclicking the Submit button, store an md5() of your form in a text file, and compare the new form’s md5 to the stored one. If they are equal, you are having a double post.

    0 讨论(0)
  • 2020-12-01 01:02

    I usually rely on the sql UNIQUE index Constraint. http://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html

    0 讨论(0)
  • 2020-12-01 01:02

    My two cents:

    • Redirect the user to the same page after sending data and verify if(isset($_POST['submit'])

    Other useful information for similar cases:

    • Give a look to LOCK TABLES in MySQL

    • Disable buttons via JavaScript after the first click

    0 讨论(0)
  • 2020-12-01 01:03

    You might want to check out the POST/Redirect/GET pattern most modern web apps implement, see http://en.wikipedia.org/wiki/Post/Redirect/Get

    0 讨论(0)
  • In addition to the good suggestions already mentioned about taking the user away from the posting page so a refresh and back button are harmless, another layer in improving your data storage is to use UUIDs as keys in your table and let your applications generate them.

    These are also known as GUIDs in the Microsoft world and in PHP you can generate one via uniqid() in PHP. This is a 32 character hex value which you should store in a hex/binary column format but if the table isn't going to be heavily used than CHAR(32) will work.

    Generate this ID when you display your form as a hidden input, and make sure to mark the database column is marked as the primary key. Now if the user does manage to go all the way back to a posting page, the INSERT will fail because you can't have duplicate keys.

    An extra bonus to this is, if you generate the UUID in code, then after you perform an insert you'll never need to use wasteful queries retrieving the key that was generated because you'll already know it. This is a nice benefit when you need to INSERT child items into other tables.

    Good programming is based upon layering your work, not relying on 1 thing to work. Despite how common it is for coders to rely on incremental IDs, they are one of the laziest ways to build a table.

    0 讨论(0)
提交回复
热议问题