title: WordPress Settings field: Saving multiple <select> options
body: <p>In a WordPress Options Page I have a settings field that has an HTML <code>select</code> with the attribute of <code>multiple</code>. The <code>select</code>'s <code>options</code> are dynamically populated by Custom Post Types, all is fine there. I can save one value into an array, but not more. This is the current <code>var_dump</code>:</p>
  
  <pre><code>array(1) { ["awc_cpt"]=&gt; string(12) "board_member" }
  </code></pre>
  
  <p>Ideally I'd like the array to return:</p>
  
  <pre><code>array(
      "board_member" =&gt; "board_member",
      "another_cpt" =&gt; "another_cpt",
      // and so on for as many Custom Post Types as needed
  )
  </code></pre>
  
  <p>I am a beginner at PHP, so I may be missing some fundamentals.</p>
  
  <p><strong>Question: How do I save multiple selected <code>options</code> into the array for this WordPress setting?</strong></p>
  
  <pre><code>&lt;?php
  
  class AWC_Redirect {
      private $awc_redirect_options;
      public $non_archived_posts = array();
  
      public function __construct() {
          if( is_admin() ){
              add_action( 'admin_menu', array( $this, 'awc_redirect_add_plugin_page' ) );
              add_action( 'admin_init', array( $this, 'awc_redirect_page_init' ) );
          }
  
          add_action( 'template_redirect', array( $this, 'AWC_template_redirect') );
      }
  
      public function awc_redirect_add_plugin_page() {
          add_options_page(
              'AWC Redirect', // page_title
              'AWC Redirect', // menu_title
              'manage_options', // capability
              'awc-redirect', // menu_slug
              array( $this, 'awc_redirect_create_admin_page' ) // function
          );
      }
  
      public function awc_redirect_create_admin_page() {
          $this-&gt;awc_redirect_options = get_option( 'awc_redirect_option_name' ); ?&gt;
  
          &lt;div class="wrap"&gt;
              &lt;h2&gt;AWC Redirect&lt;/h2&gt;
              &lt;p&gt;&lt;/p&gt;
              &lt;?php settings_errors(); ?&gt;
  
              &lt;form method="post" action="options.php"&gt;
                  &lt;?php
                      settings_fields( 'awc_redirect_option_group' );
                      do_settings_sections( 'awc-redirect-admin' );
                      submit_button();
                  ?&gt;
              &lt;/form&gt;
          &lt;/div&gt;
          &lt;?php var_dump(get_option( 'awc_redirect_option_name' )); ?&gt;
      &lt;?php }
  
      public function awc_redirect_page_init() {
          register_setting(
              'awc_redirect_option_group', // option_group
              'awc_redirect_option_name', // option_name
              array( $this, 'awc_redirect_sanitize' ) // sanitize_callback
          );
  
          add_settings_section(
              'awc_redirect_setting_section', // id
              'Settings', // title
              array( $this, 'awc_redirect_section_info' ), // callback
              'awc-redirect-admin' // page
          );
  
          add_settings_field(
              'awc_cpt', // id
              'Custom Post Types', // title
              array( $this, 'awc_cpt_callback' ), // callback
              'awc-redirect-admin', // page
              'awc_redirect_setting_section' // section
          );
      }
  
      public function awc_redirect_sanitize($input) {
          $sanitary_values = array();
          if ( isset( $input['awc_cpt'] ) ) {
              $sanitary_values['awc_cpt'] = $input['awc_cpt'];
          }
  
          return $sanitary_values;
      }
  
      public function awc_redirect_section_info() {
  
      }
  
      public function awc_cpt_callback() { 
          ?&gt; &lt;select name="awc_redirect_option_name[awc_cpt]" id="awc_cpt" multiple&gt;
              &lt;?php echo $this-&gt;AWC_get_post_types(); ?&gt;
          &lt;/select&gt; &lt;?php
      }
  
      // get all post types that are archived =&gt; true
      public function AWC_get_post_types(){
  
          $post_types = $this-&gt;AWC_list_post_types();
          $op = '';
  
          foreach ( $post_types  as $post_type ) {
              $op .= $this-&gt;AWC_get_post_details( $post_type );
          }
          return $op;
      }
  
      public function AWC_list_post_types(){
          $args = array(
              'public'   =&gt; true,
              '_builtin' =&gt; false
          );
  
          $output = 'names'; // names or objects, note names is the default
          $operator = 'and'; // 'and' or 'or'
          $op = '';
  
          $post_types = get_post_types( $args, $output, $operator );
          return $post_types;
      }
  
      // loop through and spit out into &lt;select&gt;. If they are set, mark as selected.
      public function AWC_get_post_details( $post_type ){
          $op = get_post_type_object( $post_type );
          if( !$post_type || false === $op-&gt;has_archive ){
              return;
          }
  
          $name = $op-&gt;name;
          $label = $op-&gt;label;
          $archive_link = get_post_type_archive_link( $post_type );
  
          // Had to do the following because array_push doesn't work on an empty variable... 
          // ...so set it with the first, push with the rest.
          if( empty( $this-&gt;non_archived_posts ) ){
              $this-&gt;non_archived_posts[] = $name;
          } else{
              array_push( $this-&gt;non_archived_posts, $name );
          }
  
          $selected = (isset( $this-&gt;awc_redirect_options['awc_cpt'] ) &amp;&amp; $this-&gt;awc_redirect_options['awc_cpt'] === $name ) ? 'selected' : '';
  
          $select_options = '
                  &lt;option value="' . $name . '" ' . $selected . '&gt;' . $label . '&lt;/option&gt;
          ';
  
          return $select_options;
      }
  
      public function AWC_template_redirect(){
          $post_types = $this-&gt;AWC_list_post_types();
          foreach( $post_types as $cpt ){
              if ( is_singular( $cpt ) &amp;&amp; get_post_type_object( $cpt )-&gt;has_archive ) {
                  $redirectLink = get_post_type_archive_link( $cpt );
                  wp_redirect( $redirectLink, 302 );
                  exit;
              }
          }
      }
  
  }
  
  $awc_redirect = new AWC_Redirect();
  </code></pre>