views:

58

answers:

3

The code below is first the client code, then the class file.

For some reason the 'deductTokens()' method is calling twice, thus charging an account double. I've been programming all night, so I may just need a second pair of eyes:

    if ($action == 'place_order') {

    if ($_REQUEST['unlimited'] == 200) {

        $license = 'extended';

    } else {

        $license = 'standard';

    }

    if ($photograph->isValidPhotographSize($photograph_id, $_REQUEST['size_radio'])) {

        $token_cost = $photograph->getTokenCost($_REQUEST['size_radio'], $_REQUEST['unlimited']);
        $order = new ImageOrder($_SESSION['user']['id'], $_REQUEST['size_radio'], $license, $token_cost);
        $order->saveOrder();
        $order->deductTokens();
        header('location: account.php');

    } else {

        die("Please go back and select a valid photograph size");

    }

}


######CLASS CODE#######
<?php

include_once('database_classes.php');

class Order {

    protected $account_id;
    protected $cost;
    protected $license;

    public function __construct($account_id, $license, $cost) {

        $this->account_id = $account_id;
        $this->cost = $cost;
        $this->license = $license;

    }

}

class ImageOrder extends Order {

    protected $size;

    public function __construct($account_id, $size, $license, $cost) {

        $this->size = $size;

        parent::__construct($account_id, $license, $cost);

    }

    public function saveOrder() {

        //$db = Connect::connect();
        //$account_id = $db->real_escape_string($this->account_id);
        //$size = $db->real_escape_string($this->size);
        //$license = $db->real_escape_string($this->license);
        //$cost = $db->real_escape_string($this->cost);

    }

    public function deductTokens() {

        $db = Connect::connect();
        $account_id = $db->real_escape_string($this->account_id);
        $cost = $db->real_escape_string($this->cost);
        $query = "UPDATE accounts set tokens=tokens-$cost WHERE id=$account_id";
        $result = $db->query($query);

    }

}

?>

When I die("$query"); directly after the query, it's printing the proper statement, and when I run that query within MySQL it works perfectly.

$action = $_REQUEST['action'];

account.php is just a list of orders, never does it call up downloads.php. Just tried commenting out the redirect, but I'm having the same problem. I don't understand how it's getting called twice, the die statements are showing the right query, and the script doesn't reload itself.

Here are my apache access logs:

71.*** - - [22/May/2010:13:14:35 +0000] "POST /download.php?action=confirm_download&photograph_id=122 HTTP/1.1" 200 1951 "http://***.com/viewphotograph.php?photograph_id=122" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
71.***  - - [22/May/2010:13:14:36 +0000] "GET /download.php?action=place_order&photograph_id=122&size_radio=xsmall&unlimited=0 HTTP/1.1" 302 453 "http://*** .com/download.php?action=confirm_download&photograph_id=122" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
71.***  - - [22/May/2010:13:14:36 +0000] "GET /download.php?action=place_order&photograph_id=122&size_radio=xsmall&unlimited=0 HTTP/1.1" 302 453 "http://*** .com/download.php?action=confirm_download&photograph_id=122" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
71.***  - - [22/May/2010:13:14:36 +0000] "GET /account.php HTTP/1.1" 200 2626 "http://***.com/download.php?action=confirm_download&amp;photograph_id=122" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"

I understand there's obviously something wrong here. But I can't figure out where the second request is coming from.

A: 

I know this will sound strange but make sure that you don't have tag with empty src="" attribute or any css style refering to empty url (like background: url();) on your site around the place when you have your code that runs twice.

Read about some trouble this may cause here: http://hi.baidu.com/zhenyk/blog/item/38a1051fc63b96c3a686698f.html

Kamil Szot
I had similar problem where a counter was being updated twice per request, ended up with a JavaScript error in a slideshow!
Salman A
A: 

Another long shot, but it happened to me once in Firefox - doubled page executions, resulting in doubled inserts and updates - close your browser and restart.

coolgeek
A: 

The line:

header('location: account.php');

Forwards the browser, but doesn't end the php script.
This might be fine, the code-snippet you gave doens't "do" anything after this line.

Another option might be a double-click
If you double-click on the submit button, the form will be sent twice.
We used some javascript to disable the submit button after the first click.

Bob Fanger
I already tried adding a return 0; after the redirect. And I'm making sure to only click once.
ThinkingInBits