用于检查db值是否与当前Select选项匹配的函数

I am creating a customer account page which displays the relevant information in the database and allows customers to edit their information. The code below retrieves and displays the customer's account information from the database and pre-selects the values matching their information, but since there are a few hundred select and/or multiselect elements I'd like to create a function which would check if the db value (i.e. $rows['gift_privacy']) matches the current option.

<?php   
try {  
$stmt = $conn->prepare("SELECT * FROM customer_info WHERE user_id = :user_id");  
$stmt->bindValue(':user_id', $user_id); 
$stmt->execute();
}catch(PDOException $e) {echo $e->getMessage();}
$row = $stmt->fetch();
?>
<form action="account_information-exec.php" method="post">
<select name="gift_privacy">
    <option value="Standard" <?php if($row['gift_privacy']=='Standard') echo "selected='selected'"; ?>>Standard</option>
    <option value="Gift_ID_Req" <?php if($row['gift_privacy']=='Gift_ID_Req') echo "selected='selected'"; ?>>Require program ID</option>
    <option value="Not_Enrolled" <?php if($row['gift_privacy']=='Not_Enrolled') echo "selected='selected'"; ?>>Do not enroll</option>
</select>
<input type="submit" value="submit">
</form>

Edit - The code differs slightly for the multiselect elements. The element names are followed by square brackets (i.e. name="notifications[]"), and values are inserted into the database as imploded arrays implode(',', $_POST['notifications']). Those commas are then stripped from fetched values in order to properly compare them to the option's values $row1 = str_replace(',', '', $row);

Existing Function

This function applies selected="selected" to the correct options, but it's too cumbersome for me to use with so many elements and I'm not sure how to modify the code so that it could be easily applied to all the select and/or multiselect elements. Also, since the page currently uses standard select elements with hard-coded options I'm hoping for a solution that doesn't require creating arrays for each element.

<select name="gift_privacy">
    <?php
    $gifts = array("Standard" => "Standard", "Gift_ID_Req" => "Require Program ID", "Not_Enrolled" => "Do not Enroll");
    $gift = $row['gift_privacy'];
    foreach($gifts as $key => $value) {
    if($key == $gift) {
        echo '<option selected="selected" value="'. $key .'">'. $value .'</option>';
    } else {
        echo '<option value="'. $key .'">'. $value .'</option>';
    }
    }
    ?>
</select> 

I faced the same problem once and solved it by creating a function (or a class static method) to handle my option lists.

To print out your options you will have to cycle through them anyway, so while you cycle there is nothing bad in checking for each one if it must be the currently selected.

Just create a function like:

function printSelectOptions($dataArray, $currentSelection) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (($key == $currentSelection) ? 'selected="selected"' : '') . ' value="' . $key . '">' . $value . '</option>';
    }
}

Giving $dataArray as your key/value options array, and $currentSelection as the key of the selected option.

So in your code you will have just calls to this function, like:

<select id='mySelect' name='mySelect'>
    <?php echo printSelectOptions($gifts, $gift); ?>
</select>

This should do the work!

EDIT: Adding sample to work with select multiple...

<?php
$options = array(   1   =>  "Test 1",
                    2   =>  "Test 2",
                    3   =>  "Test 3");

$selected = array(1, 3);

function printSelectOptions($dataArray, $selectionArray) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (in_array($key, $selectionArray) ? 'selected="selected"' : '') . ' value="' . $key . '">' . $value . '</option>';
    }
}
?>

<select multiple>
    <?php echo printSelectOptions($options, $selected); ?>
</select>

The trick is passing the selected values as an array of keys, instead of a single key. In the sample I provided dummy arrays, but obviously you'll have to build yours from database... :)

EDIT: Select multi with arrays taken from the question...

<?php
$gifts = array("Standard" => "Standard", "Gift_ID_Req" => "Require Program ID", "Not_Enrolled" => "Do not Enroll");
$gift = array($row['gift_privacy']);

function printSelectOptions($dataArray, $selectionArray) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (in_array($key, $selectionArray) ? 'selected="selected"' : '') . ' value="' . $key . '">' . $value . '</option>';
    }
}
?>

<select multiple>
    <?php echo printSelectOptions($gifts, $gift); ?>
</select>

EDIT: Explode multiple selected values

If you have mutliple selected values as a comma separated string, you just have to explode it before passing to the function I provided...

$selectedOptionsArray = explode(',', $selectedOptionsString);

So the ending code will look like...

<?php
$gifts = array("Standard" => "Standard", "Gift_ID_Req" => "Require Program ID", "Not_Enrolled" => "Do not Enroll");
$gift = explode(',', $row['gift_privacy']);

function printSelectOptions($dataArray, $selectionArray) {
    foreach ($dataArray as $key => $value) {
        echo '<option ' . (in_array($key, $selectionArray) ? 'selected="selected"' : '') . ' value="' . $key . '">' . $value . '</option>';
    }
}
?>

<select multiple>
    <?php echo printSelectOptions($gifts, $gift); ?>
</select>

Use simpler method:

<?php
 echo '<option '.($key == $gift ? 'selected="selected" ' : '').'value="'. $key .'">'. $value .'</option>';
?>

Edit: second option

 echo '<option '.selected_option($key, $gift).'value="'. $key .'">'. $value .'</option>';

 function selected_option($val1, $val2){
  if($val1 == $val2){
   return 'selected="selected" ';
  }else{
   return '';
  }
 }

There is nothing wrong with what you have, and this, or something very similar is the typical approach to this problem.

You would/could wrap it in an actual function, say print_select( $array, $selected ); which would/could print out the entire <select> including the select themselves.

The final code might be:

print_select( $gifts, $selected_gift );
print_select( $colors, $selected_color );
// etc

You could use a function like this to simplify it:

<?php
function renderOption($key, $value, $current) {
    echo '<option value="' . $key . '"' . ($key == $current ? ' selected="selected"' : '') . '>' . $value. '</option>';
}
?>

<select name="gift_privacy">
    <?php
    $gifts = array("Standard" => "Standard", "Gift_ID_Req" => "Require Program ID", "Not_Enrolled" => "Do not Enroll");
    $gift = $row['gift_privacy'];
    foreach($gifts as $key => $value) 
        renderOption($key, $value, $gift);
    ?>
</select>