Code Bytes
Generate a year dropdown in PHP
Build a labelled year select with integer comparisons, a deliberate timezone and validation of a requested selected year.
Generate the range, keep the choice explicit
A small loop is easier to maintain than a long hand-written list of years. This example lists the current year down to 1950 and optionally selects a valid year query parameter.
The useful fixes over the old example are a real PHP opening tag, integer year values, a label/name for the field, and validation before using an incoming selection.
PHP template
<?php
$earliest = 1950;
$latest = (int) (new DateTimeImmutable('now', new DateTimeZone('Europe/London')))
->format('Y');
if ($earliest > $latest) {
throw new LogicException('The year range is reversed.');
}
$selected = $latest;
if (array_key_exists('year', $_GET)) {
$selected = is_string($_GET['year'])
? filter_var($_GET['year'], FILTER_VALIDATE_INT, ['options' => [
'min_range' => $earliest, 'max_range' => $latest,
]])
: false;
}
?>
<label for="year">Year</label>
<select id="year" name="year" required>
<option value=""<?= $selected === false ? ' selected' : '' ?>>Choose a year</option>
<?php for ($year = $latest; $year >= $earliest; $year--): ?>
<option value="<?= $year ?>"<?= $year === $selected ? ' selected' : '' ?>><?= $year ?></option>
<?php endfor; ?>
</select>
Save it in a PHP template and serve it through PHP. A URL ending in ?year=2024 selects 2024 when that year is in range. A missing parameter uses the current year; an invalid or array-shaped value leaves the placeholder selected rather than pretending it was accepted.
Adapt the bounds to the task
Change 1950 to the genuine earliest useful year. A booking form might need future years instead; a year-of-birth field should not silently default to the current year. For a large or uncertain range, a labelled text input with a clear example can be easier than a long select.
The values printed here are generated integers, not raw query strings. If you add user-controlled labels or attributes, escape them for their HTML context. The handler receiving the eventual form submission must repeat the range validation—rendering valid options does not prevent a forged request. A cached page also needs refreshing when its upper year changes.
References: PHP integer validation and DateTimeImmutable.
Original version9 December 2014
Kept here for reference and earlier links. The updated guide above is the recommended starting point; older code may depend on retired services or different software versions.
A very common feature of forms is the dropdown
<select>
</select>
box, commonly using a range of years as the options.
Writing and maintaining these long list of options/years can be very monotonous via plain HTML.
This following codebyte generates a simple select box, with an for each year based on some basic arguments.
Change $currently_selected to be the option you want as the top/default option of the select box.
$earliest_year to be the lowest year you want the range to start at.
$latest_year to be the highest year you want your range to go to.
<!--?php
// Sets the top option to be the current year. (IE. the option that is chosen by default).
$currently_selected = date('Y');
// Year to start available options at
$earliest_year = 1950;
// Set your latest year you want in the range, in this case we use PHP to just set it to the current year.
$latest_year = date('Y');
print '<select>';
// Loops over each int[year] from current year, back to the $earliest_year [1950]
foreach ( range( $latest_year, $earliest_year ) as $i ) {
// Prints the option with the next year in range.
print '<option value="'.$i.'"'.($i === $currently_selected ? ' selected="selected"' : '').'>'.$i.'</option>';
}
print '</select>';
?-->
The above code byte generates:
Keep exploring