You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress插件自定义设置页多选字段保存异常求助

WordPress 插件多选设置字段无法保存多个值的解决方法

开发WordPress插件自定义设置页时遇到多选字段保存异常:该字段仅能保存单个选中值,选中多个选项时无法全部保存。尝试在字段名称后添加[]但无效,推测字段已处于数组中,但问题仍未解决。

相关代码

add_action( 'admin_init', 'settings_Init' );
function settings_Init() { 

    register_setting( 
        'Plugin_Settings', // 设置组名称
        'Plugin_Settings_Sanitize' // 要保存的选项名称
    );

    add_settings_section(
        'Plugin_Settings_Section', // 区块ID
        __( 'Settings', 'textdomain' ), // 区块标题
        'Settings_Section_Callback', // 区块回调函数
        'Plugin_Settings' // 设置页面slug
    );

    add_settings_field( 
        'Select_Field', 
        __( 'Directory', 'textdomain' ), 
        'Render_Select', 
        'Plugin_Settings', 
        'Plugin_Settings_Section' 
    );
}

function Settings_Section_Callback() { 
    echo __( 'This below options must be configured to ensure the plugin works as expected.', 'textdomain' );
}

function Render_Select() { 
    $options = get_option( 'Plugin_Settings_Sanitize' );
    $products = wc_get_products(array(
        'type' => 'course',
        'status' => 'published',
        'limit' => -1,
    ));?>
    
        <select class="" name='Plugin_Settings_Sanitize[Select_Field]' multiple>
            <?php foreach($products as $product){?>
                <option value='<?php echo $product->get_id();?>' <?php selected($options['Select_Field'], $product->get_id());?>>
                    <?php echo $product->get_title();?>
                </option>
            <?php }?>
        </select>
    <?php
}

function options_page() { ?>
    <form action='options.php' method='post'>
        <h2>Platform</h2>
        <?php var_dump($_POST);?>
        <?php settings_errors(); ?>
        <?php settings_fields( 'Plugin_Settings' ); 
        do_settings_sections( 'Plugin_Settings' ); 
        submit_button();?>
    </form>
<?php }

前端渲染的HTML

<select class="" name="Plugin_Settings_Sanitize[Select_Field]" multiple="">
    <option value="17">This is a course test (Copy)</option>
    <option value="14" selected="selected">This is a course test</option>
</select>

问题原因分析

  1. name属性缺失[]:即使字段嵌套在数组中,多选select的name必须加上[],否则PHP只会接收最后一个选中的值,而非数组。
  2. 选中状态判断逻辑错误:当保存的值是数组时,selected()函数的第二个参数是单个ID,无法直接匹配数组;同时未处理选项未设置时$options['Select_Field']为空的情况,会触发PHP警告。
  3. 未配置 sanitize 回调:register_setting()未指定 sanitize 函数,WordPress默认过滤逻辑可能会丢弃数组类型的值,导致无法保存。

解决方案

1. 修改select的name属性

将name='Plugin_Settings_Sanitize[Select_Field]'改为name='Plugin_Settings_Sanitize[Select_Field][]',让PHP识别为数组格式。

2. 修复选中状态判断逻辑

在Render_Select()函数中,先检查保存的值是否为数组,再用in_array()判断当前选项是否被选中:

$selected = isset($options['Select_Field']) && is_array($options['Select_Field']) ? in_array($product->get_id(), $options['Select_Field']) : false;
selected($selected, true);

3. 添加 sanitize 回调函数

在register_setting()中添加 sanitize 回调,确保数组能被安全保存:

register_setting( 
    'Plugin_Settings', 
    'Plugin_Settings_Sanitize',
    array(
        'sanitize_callback' => 'sanitize_plugin_settings'
    )
);

同时定义 sanitize 函数,过滤非法值:

function sanitize_plugin_settings($input) {
    $sanitized_input = array();
    if (isset($input['Select_Field']) && is_array($input['Select_Field'])) {
        $sanitized_input['Select_Field'] = array_map('absint', $input['Select_Field']);
    } else {
        $sanitized_input['Select_Field'] = array();
    }
    return $sanitized_input;
}

修改后的完整代码

add_action( 'admin_init', 'settings_Init' );
function settings_Init() { 

    register_setting( 
        'Plugin_Settings', 
        'Plugin_Settings_Sanitize',
        array(
            'sanitize_callback' => 'sanitize_plugin_settings'
        )
    );

    add_settings_section(
        'Plugin_Settings_Section',
        __( 'Settings', 'textdomain' ),
        'Settings_Section_Callback',
        'Plugin_Settings'
    );

    add_settings_field( 
        'Select_Field', 
        __( 'Directory', 'textdomain' ), 
        'Render_Select', 
        'Plugin_Settings', 
        'Plugin_Settings_Section' 
    );
}

function Settings_Section_Callback() { 
    echo __( 'This below options must be configured to ensure the plugin works as expected.', 'textdomain' );
}

function sanitize_plugin_settings($input) {
    $sanitized_input = array();
    if (isset($input['Select_Field']) && is_array($input['Select_Field'])) {
        $sanitized_input['Select_Field'] = array_map('absint', $input['Select_Field']);
    } else {
        $sanitized_input['Select_Field'] = array();
    }
    return $sanitized_input;
}

function Render_Select() { 
    $options = get_option( 'Plugin_Settings_Sanitize', array() );
    $products = wc_get_products(array(
        'type' => 'course',
        'status' => 'published',
        'limit' => -1,
    ));?>
    
        <select class="" name='Plugin_Settings_Sanitize[Select_Field][]' multiple>
            <?php foreach($products as $product){
                $product_id = $product->get_id();
                $selected = isset($options['Select_Field']) && is_array($options['Select_Field']) ? in_array($product_id, $options['Select_Field']) : false;
            ?>
                <option value='<?php echo $product_id;?>' <?php selected($selected, true);?>>
                    <?php echo esc_html($product->get_title());?>
                </option>
            <?php }?>
        </select>
    <?php
}

function options_page() { ?>
    <form action='options.php' method='post'>
        <h2>Platform</h2>
        <?php settings_errors(); ?>
        <?php settings_fields( 'Plugin_Settings' ); 
        do_settings_sections( 'Plugin_Settings' ); 
        submit_button();?>
    </form>
<?php }

内容的提问来源于stack exchange,提问作者Daniel Vickers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:45:34