問題描述
我使用的是設置 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。