views:

836

answers:

4

Bit of a strange problem here...

I've got an update query that isn't working, and I can't for the life of me work out why!

My table has two three fields - 'id' (int, auto increment), 'date' (date), and 'amountraised' (decimal). Part of the app I'm developing calculates the fundraising total each week made by a charity bookstall. The 'date' field uses a date column type as elsewhere on the site I'm using the dates in calculations.

Elsewhere within the system I've got other update queries that are working just fine, but I suspect the problem with this one is that as well as updating the record I'm also trying to manipulate the date format as well (so that I can enter dates in the British dd-mm-yyyy format and then use the PHP to convert back into the MySQL-friendly yyyy-mm-dd format.

This is the strange bit. According to the confirmation page on the site, the query has run okay, and the update's been made, but when I check the database, nothing's changed. So I could check what the output of the query is I've tried echoing the result to the web page to see what I'm getting. The expected values show up there on the page, but again, when I check the database, nothing's been updated.

This is my update form with the date conversion function:

          function dateconvert($date,$func) {
          if ($func == 1){ //insert conversion
          list($day, $month, $year) = split('[/.-]', $date); 
          $date = "$year-$month-$day"; 
          return $date;
          }
          if ($func == 2){ //output conversion
          list($year, $month, $day) = split('[-.]', $date); 
          $date = "$day/$month/$year"; 
          return $date;
            }
          } // end function      
          require_once('/home/thebooks/admins/connect.php');
          $id = $_GET['id'];
          $dateinput = $_GET['dateinput'];
          $query = "SELECT * FROM fundraisingtotal WHERE id='$id'";
          $result = mysql_query($query);
          $row = mysql_fetch_array($result);
          extract($row);
          $date = $row['date']; //your mysql date
          $realdate = dateconvert($date,2); // convert date to British date
          $amountraised = stripslashes($amountraised); //amount raised
          mysql_close();?>
            <div id="title">Update Fundraising Total</div>
            <form id="updatetotals" action="updated.php" method="post">
                <div class="row"><label for="dateinput" class="col1">Date&nbsp;&nbsp;</label><span class="col2"><input id="dateinput" name="dateinput" type="text" size="25" value="<?php echo $realdate ?>" maxlength="10" /></span></div>
                <div class="row"><label for="amountraised" class="col1">Fundraising Total&nbsp;&nbsp;</label><span class="col2"><input id="amountraised" name="amountraised" type="text" size="25" value="<?php echo $amountraised ?>" maxlength="7" /></span></div>
                <div class="submit"><input type="submit" name="submitted" value="Update" /><input type="reset" name="reset" value="Clear the form" /></div>
                <input type="hidden" name="id" value="<?php echo $id ?>" />
            </form>

...and this is the form processing/query page:

    require_once('/home/thebooks/admins/connect.php');
    $dateinput = $_POST['dateinput'];

    // Date conversion from: http://www.phpbuilder.com/annotate/message.php3?id=1031006
    // using type 1
    $convdate = $_POST['dateinput']; // get the data from the form
    $convdate = dateconvert($convdate, 1); // Would convert to e.g. 2005-12-19 which is the format stored by mysql

    function dateconvert($convdate,$func) {
    if ($func == 1){ //insert conversion
    list($day, $month, $year) = split('[/.-]', $convdate); 
    $date = "$year-$month-$day"; 
    return $date;
    }
    if ($func == 2){ //output conversion
    list($year, $month, $day) = split('[-.]', $convdate); 
    $date = "$day/$month/$year"; 
    return $date;
      }
    }
    $date = "$convdate";
    $amountraised = $_POST['amountraised'];         

    $update = "UPDATE fundraisingtotal SET date = '$date', amountraised = '$amountraised' WHERE id='$id' ";
    $result = mysql_query($update);
    $realdate = dateconvert($date,2); // convert date to British date 
    if ($result) {
    echo "<p class=\"dbpara\">Thank you. Your update to the record was successful.</p>";
    echo "<p class=\"dbpara\">The record has been amended to a date of <b>$realdate</b> and amount of <b>$amountraised</b>.</p>";
    }
    else {
    echo "<p>Nothing has been changed.</p>";
    }
    mysql_close();

The weird thing is that the confirmation text "The record has been amended to...etc." displays exactly as expected, but when I check the database, the record hasn't been updated at all.

I'm sure it must be something I'm missing with messing with the date formats or I've got something in the wrong order, but I've tried so many different variations on this now I can't see the wood for the trees. Anyone any ideas what I'm doing wrong here?

+2  A: 

Change

$result = mysql_query($update);

to

$result = mysql_query($update) or die(mysql_error());

And you should see what the problem is when the query fails.

Mike B
Thanks. Just tried that and the query isn't failing (or at least I'm not getting any error messages showing)...okay, edit - I've just realised that that's obviously because my hosting must be set to 'errors off' - I've just added in an 'all errors' instruction at the top of the page and realised straight away that I'd forgotten to declare the 'id' variable on that page! I knew it would be something ridiculously simple I'd missed! *blush* Thanks!
NeonBlue Bliss
No worries. I guarantee every developer has made that same mistake, or another one where the solution was equally 'humbling'. :)
Mike B
+2  A: 

I see some red-flags here. You are getting the date from a form and inputing it into MySQL without any form of validation - that could lead to SQL-injections.

Start by changing dateconvert function to something more secure. This function will always return a correct formated date, even if the user tries to abuse the system.

Edit 1: Forgot to put a : after case 'en_en' but fixed it now. Thanks neonblue.
Edit 2: Forgot to feed the date() function with the timestamp. Fixed!
Edit 3: A preg_replace to convert frontslashes to dashes

// this function always returns a valid date
function dateconvert($date = NULL, $date_type = 'sql') {
        $date = preg_replace("/", "-", $date);
    $timestamp = strtotime($date);
    switch($date_type) {
        default: case 'sql' : return date('Y-m-d', $timestamp); break; // prints YYYY-MM-DD
        case 'en_EN' : return date('d-m-Y', $timestamp); break; // prints DD-MM-YYYY
    }
}

You can always have a look into Zend_Date that will let you work with dates on your own format.

Frankie
The update's working fine now I've fixed the problem with the $id variable I forgot to declare. I'm having problems getting this function to work though. The default case is giving me a parse error "syntax error, unexpected ':'" I copied and pasted the code rather than re-typing, and I can't see what it's complaining about.
NeonBlue Bliss
Thanks for noticing neonblue! I wrote it here on SO and didn't test it... the "compiler" is always right! ;) It should work properly now.
Frankie
Thanks Frankie. Another bit of a problem now though. It's updating the record nicely (i.e. it's actually altering the record now, and of course it does help that I've got the right id declared now, but the function's changing the date to today's date. For example I've just tried updating this week's record which has a date of 11/11/09 which displays perfectly on the page where the records are listed, but when I try to update, on the update form it changes the date to today's date and even changing it back to 11/11/09 on the update form, it saves as today's date. Most odd!
NeonBlue Bliss
@neonblue, thanks for pointing it out! The date() function must be feed with a timestamp or it will assume the current one... that was the reason the output value was always the current time/date. Fixed!
Frankie
@Frankie - thank you so much! That works perfectly now - thanks for all your help! :)
NeonBlue Bliss
Oh dear! I spoke too soon. It did seem to be working, up now it's switching the day and month around. On the update page form all seems to be in order, and the date's displaying right, but when I try to update (or add a new record) it switches the day and month round, either turning 5/1/09 to 1/5/09 for example, or anything that it can't make sense of as a date, returning 01/01/1970.
NeonBlue Bliss
After looking into this further, I think I was lucky with the first date that I tried because it was 11/11/09, so didn't notice that the month and date had been switched around. Reading further on the strtotime function it seems the problem is because strtotime doesn't recognise the d/mm/yyyy format.
NeonBlue Bliss
Hi! I've studied the function and you are correct. It does not accept dates with / so your stuck with replacing the slashes or using something like Zend_Date. I've edited the question to better reflect the changes done.
Frankie
+1  A: 

Three things I would look for:

  1. Is the code attaching to the same database you are looking at? (I spent a few hours on this one ;)

  2. Is another update statement (or this one) running immediately afterwards that would change the values back? Here you need some logging to figure it out.

  3. If you echo the sql, what happens when you run it directly yourself?

Chris Lively
+1  A: 

If you see the table is not changing any value but the query does not show you any error, then WHERE id = '$id' is not hitting the register you intended to.

Don't forget to sanitize your queries as others are telling you.

Ast Derek