0

I have a form in dashboard.php to create invoice and this is submitted to invoice.php

Now my invoice.php inserts the Invoice and the customer into the database and then shows me a invoice order filling form.

if i refresh this page, it inserts a new invoice for the same customer, how do i avoid this.

I was reading that we could avoid it by redirection, but in my case how do i use it. Some thing like a PRG(post/redirect/get) how to use it?

Do i need to make an intermediate page before going to insert items to invoice

azzaxp
  • 697
  • 5
  • 11
  • 26

4 Answers4

4

The pattern you've heard about is this: Post/Redirect/Get. In general, POST is for actions, GET is for views. So you never show a user a page on a POST request. Instead, you redirect them to a page they'll request with GET, which will not cause any changes in your database.

grossvogel
  • 6,694
  • 1
  • 25
  • 36
  • can you share me a eg. code how to request from get, when the variable was already posted. – azzaxp Apr 14 '12 at 20:05
  • 1
    @azzaxp: It looks like you've gathered this from @zolex's answer above... The way to redirect the user's browser to request the next (or the same) page via GET is with `header ('Location: /page/to-view/');` – grossvogel Apr 14 '12 at 20:19
1

after successful form submission do a redirect to the same page and optionally indicate that the submission was successful

Example: invoice.php

if (count($_POST)) {

    if (/*post data is valid*/) {

        /*do whatever is needed*/
        header('Location: invoice.php?success');
    }
} else if (isset($_GET['success'])) {

     echo "Form successfuly submitted";
}
Andreas Linden
  • 12,489
  • 7
  • 51
  • 67
  • It seems working that I cannot refresh the page, but can you show me a way hot use get and get some variables which were posted in the form, which were not not put into database, but instead would be used in the page for some other things, say eg. i want the tax info here to be displayed, which is now unknown.. how to use get here..! – azzaxp Apr 14 '12 at 20:03
  • 1
    you can store those values in the session – Andreas Linden Apr 14 '12 at 20:06
  • 1
    like in first block $_SESSION['tax'] = $_POST['tax']; and in the second block echo $_SESSION['tax']; to make this work you have to call session_start(); once ie. at the top of your file – Andreas Linden Apr 14 '12 at 20:07
  • To display info about the invoice you just generated, I'd prefer looking it up by an invoice ID on the GET request. When your POST request generates the invoice, get the ID from your database, then redirect the user to a page showing info for that invoice. `header ('Location: invoice.php?invoiceid=123');` Using the session is not necessary. – grossvogel Apr 14 '12 at 20:53
1

Let dashboard.php post the form data to insert.php, which will process the data and then forward to invoice.php. Use sessions to transport the data from one file to another. Here is insert.php:

<?php

session_start();

if (session_is_registered("invoiceVars"))
    session_unregister("invoiceVars");

if (!session_is_registered("errors"))
    session_register("errors");

$errors = array();

if (!session_is_registered("formVars"))
    session_register("formVars");

foreach($_POST as $f_varname => $f_value)
    $formVars[$varname] = trim(EscapeShellCmd(stripslashes($value)));

// process your data and write it to the database or return to dashboard.php with errors, then:

session_unregister("errors");

session_register("invoiceVars");

$invoiceVars = array();
foreach ($formVars as $i_varname => $i_value)
    $invoiceVars[$i_varname] = $i_value;

session_unregister("formVars");

// add additional variables
$invoiceVars["coupon"] = 'unique_coupon_code';

// invoice.php will process the data and display it
// it has session_start(); at the top, to have $invoiceVars available
header('Location: invoice.php');
exit();

?>

header(); and exit(); will flush $_POST, so it is no longer available when the user hits back on his browser.

  • you mean to say to have a intermediate page again.. I guess ZOLEX has given a good idea, and seems to work. – azzaxp Apr 14 '12 at 20:16
  • Yes, his idea works, but it might be that you would like to forward data to your invoice that you don't want to be visible in an URL and that will be processed in invoice.php. For example you might award a user with a coupon, and you don't want him to pick the code to create that coupon out of your URL, because then he will bookmark invoice.php?coupon=9823897453 and call it again and again to profit from your mistake ;-) –  Apr 14 '12 at 20:23
  • Hmm..! Thats also thought provoking. May be i can use this in some other module. Thanks.. – azzaxp Apr 15 '12 at 06:16
0

Here is an example code for you:

# database.php
$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
session_start();

# dashboard.php
require_once("database.php");

function getSavedValue() {
    global $db;
    $sql = "SELECT input_text FROM temp_table WHERE sess_key='?'";
    $query = $db->prepare($sql);
    $query->bindParam(session_id());
    $query->execute();
    if ($query->rowCount() == 1)
        return $query->fetch();
    else
        return " ";
}

<form action="invoice.php" method="POST">
  <input type="text" name="getThisInfo" value="<?php echo getSavedValue(); ?>"/>
  <input type="submit" value="Send"/>
</form>

# invoice.php
if (isset($_POST["getThisInfo"]) && /* validation check */ 1) {
    require_once("database.php");
    $textInput = $_POST["getThisInfo"];
    $sql = "INSERT INTO perm_table(invoice_info) VALUES('?');";
    $query = $db->prepare($sql);
    $query->bindParam($textInput);
    $query->execute();
    $rows = $query->rowCount();
    echo "$rows invoices were inserted.";
    unset($_POST["getThisInfo"]);
    header("success.php");
} else {
    header("dashboard.php");
}
Ozzy
  • 8,244
  • 7
  • 55
  • 95