tags:

views:

1022

answers:

3

Users would select their date from 3 dropdowns (day, month, year). I will combine them on server-side to make a string like '2008-12-30'. How can I then validate to make sure this date was in the right format/numeric only, etc?

A: 

You can check that the date is valid using checkdate. If you want to make sure that the values are numeric and the correct length, you could do something as simple as an is_int ctype_digit and a strlen combination before you build the date.

// untested
if( !ctype_digit)( $month ) || strlen( $month ) != 2 ) {
    // handle error
}
// repeat for $day and $year
if ( checkdate( $month, $day, $year ) {
    // do your work
}
gpojd
I changed my answer from is_int to ctype_digit based on thomasrutter's comment that is_int won't handle POST variables correctly.
gpojd
+3  A: 

If they are 3 separate drop-downs, you will need to validate them as three separate values.

Ie,

  • Validate that the year column is numeric and between whatever years are valid in your app
  • Validate that the month column is numeric
  • Validate that the day column is numeric
  • Validate that they are all valid values using checkdate()

Or, you could just cast them all to integer, combine them together into a date, and see if the resulting date is valid. Ie,

$time = mktime(0, 0, 0, (int)$_POST['month'], (int)$_POST['day'], (int)$_POST['year']);

// in this example, valid values are between jan 1 2000 (server time) and now
// modify as required
if ($time < mktime(0, 0, 0, 1, 1, 2000) || $time > time())
  return 'Invalid!';

$mysqltime = date('Y-m-d', $time);

// now insert $mysqltime into database

The downside to this method is that it'll only work with dates within the Unix timestamp range ie 1970 to 2038 or so.

thomasrutter
You probably want to check if it is an integer, not if it is numeric. is_numeric is true for floats as well as integers, but is_int only checks for integers.
gpojd
is_int() cannot work on user-submitted variables, ie variables in $_POST, because these are always of type string. You could, however, cast them to integer using (int)$_POST['var'] and then loosely compare that to the original string value (using ==).
thomasrutter
A: 

If you have three dropdowns then the values coming from the dropdowns should always be numbers since you control the values associated with the month (shown below). This would then lead to the conclusion that the combined result is valid.

<option value="01">January</option>

If you provide provide assistance entries in the drop downs such as "Select a Month" then you can make that value 0 and ensure that the values coming from each drop box is greater than zero.

There is the possibility that someone will alter the HTML form to provide other values. If this is a concern then you can use the PHP function ctype_digit() to check that each value provided is actually a numerical digit.

If your concern is that the date is actually valid the use the checkdate() function.

Paulo
Its possible to make posts to a script without the use of forms. I can write a bot that makes a post to your form and posts whatever value i put in for each field without the use of forms.
Click Upvote
That's true which is why the suggestion of using ctype_digit() and checkdate() make sense. I was basing my answer on the statement that you had a form. Even if you use a script, there aren't many cases in this instance in which it wouldn't use the values in the forms.
Paulo