问题描述

我使用的是设置 API,我无法让复选框工作,如果他们设置为”false” 他们甚至不是 $ _POST,这就是重点。

Stephen Harris & Chip Bennett explained it,但我相信他们的方式不够简单 (特别是对我来说,根本不是 PHP-guy) 。我真的需要几个自定义 PHP 函数和 custom-named 提交按钮为每个窗体只是为了让这个简单的事情工作?

我的设置看起来很像:

register_setting('XX_theme_settings', 'XX_theme_settings', 'setting_validate' );

add_settings_section('theme_options', 'Theme Options', 'theme_options_generate', 'page1' );
add_settings_field( 'XX_Option1', 'Option 1', 'checkbox', 'page1', 'theme_options', 'XX_Option1', $args = array('id' => 'checkbox1', 'type' => 'checkbox') );
add_settings_field( 'XX_Option2', 'Option 2', 'checkbox', 'page1', 'theme_options', 'XX_Option2', $args = array('id' => 'checkbox2', 'type' => 'checkbox') );

然后我用这个回调函数生成复选框:

function checkbox($args) {
    $options = get_option('XX_theme_settings');
    echo '<input type="checkbox" name="'. $args['id'] .'" value="true"'; if($options[$args['id']]==true) { echo 'checked="checked'; }; echo '/>';
    echo $args['type'];
}

现在,我需要的一切都是一个很好的验证回调:

function setting_validate($input) {
   // Firstly it should find all fields of type == "checkbox"
   // (I'm not sure why should I check which field was just being sent,
   // is updating all the checkboxes from different sections a big no-no?
   // it is much easier indeed.
   // Now set the ones missing to false/0 and the rest to true/1.
   // Then merge everything like below:

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);
   return $merged;
}

所以问题是:如何列出所有设置 Api 复选框,然后将正确的设置为 true?

我想看起来像这样:

$options = array(
        array(
            'id' => 'checkbox1',
            'type' => 'checkbox',
            'page' => 'page1',
         ),
        array(
            'id' => 'checkbox2',
            'type' => 'checkbox',
            'page' => 'page1',
         ),
);

function setting_validate($input) {
   foreach($options as $option) {
     if($option['type'] == "checkbox") {
        //set it to 1 if sent
     }
   }

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);
   return $merged;
}

谢谢 :)

Here’s how Chip Bennett does it exactly,但即使所有这些伟大的意见,我无法得到它如何正确的工作。

最佳解决思路

如果有问题的设置是 $setting,并且是一个复选框,您可以这样验证:

<?php
$valid_input[$setting] = ( isset( $input[$setting] ) && true == $input[$setting] ? true : false );
?>

在这种情况下,$input 是传递给验证回调的表单数据,其中 $input 是 array-of-arrays 。验证方法称为白名单,调用当前设置数组 (在本例中为 $valid_input),并且只有当 $input[$setting]中的值通过验证时,才会更改设置数组中的每个设置。

使用复选框,如果未设置复选框,则该设置本身不会填充到 $input 数组中。所以验证它的第一步是确定它是否已经在 $input 中设置。第二步是确保设置的值为 true(或'true',或'on',或在设置窗体中设置复选框值的任何值) 。如果满足这两个条件,返回 true; 否则返回 false

看:真的很简单:)

Edit

关于这一点:

function setting_validate($input) {
   foreach($options as $option) {
     if($option['type'] == "checkbox") {
        //set it to 1 if sent
     }
   }

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);
   return $merged;
}

… 这不完全是你想要做的。您希望将返回值限制为有效选项; 也就是说,您想要明确地返回您已经定义的知道的设置。如果某些人可以使用附加数据 (即恶意代码) 来填充 $input,那么您的方法只会将该附加数据直接传递到数据库中。

不要做 array_merge()。单独/单独更新每个 $valid_options[$setting],只能返回 $valid_options

这是以下过程:

  1. 定义当前有效的数据:

    $valid_input = get_option( 'XX_theme_settings' );
    
  2. 只有 $input 通过验证/消毒,才能使用 $input 更新当前有效的数据。

  3. 然后返回更新的当前有效数据。

如果这些字段是动态生成的,那么您也应该在验证回调中动态地逐步执行这些字段。你有这个正确的,与 foreach( $options as $option )

把它放在一起可能看起来像这样:

<?php
function setting_validate( $input ) {
    // Get current setting values
    $valid_options = get_option( 'XX_theme_options' );
    // Get option parameters array
    // Note: XX_theme_get_option_parameters() function
    // should be defined to return the array you've
    // defined for $options
    $options = XX_theme_get_option_parameters();
    // Now step through the option parameters,
    // and validate each $input[$option]
    foreach( $options as $option ) {
         // If $option['type] is a checkbox
         if( 'checkbox' == $option['type'] ) {
             // verify that $input[$option] is set
             // and is set with a valid value;
             // if so, set $valid_input[$option] to 1
             $valid_input[$option] = ( isset( $input[$option] && true == $input[$option] ? 1 : 0 );
         }
     }
     // Return the updated $valid_input array
     return $valid_input;
}
?>

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。