问题描述
我使用的是设置 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
。
这是以下过程:
-
定义当前有效的数据:
$valid_input = get_option( 'XX_theme_settings' );
-
只有
$input
通过验证/消毒,才能使用$input
更新当前有效的数据。 -
然后返回更新的当前有效数据。
如果这些字段是动态生成的,那么您也应该在验证回调中动态地逐步执行这些字段。你有这个正确的,与 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。