函数文档

register_setting()

💡 云策文档标注

概述

register_setting() 函数用于在 WordPress 中注册一个设置及其数据,允许开发者定义选项的组、名称、类型、验证回调等参数,以便在管理界面和 REST API 中安全地存储和检索设置值。

关键要点

  • 函数接受三个参数:$option_group(设置组名,如 'general')、$option_name(选项名)和可选的 $args 数组,用于指定类型、标签、描述、sanitize_callback、show_in_rest 等。
  • 支持的数据类型包括 'string'、'boolean'、'integer'、'number'、'array' 和 'object',其中 'array' 和 'object' 类型在 REST API 中需要定义 schema。
  • sanitize_callback 用于验证和清理选项值,但需注意在首次提交时可能被调用两次,建议通过静态变量或初始化选项来避免重复执行。
  • show_in_rest 参数控制设置是否包含在 REST API 中,若为 true 或数组,需在 rest_api_init 钩子中注册以确保生效。
  • 使用 register_setting() 时,同一 $option_group 下的所有设置的 sanitize_callback 会在保存该组时都被触发,即使设置不在当前页面。
  • 函数内部处理了向后兼容性,如 $new_whitelist_options 重命名为 $new_allowed_options,并废弃了 'misc' 和 'privacy' 选项组。

代码示例

// 基本示例:注册一个字符串类型设置
function register_my_setting() {
    $args = array(
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
        'default' => NULL,
    );
    register_setting( 'my_options_group', 'my_option_name', $args );
}
add_action( 'admin_init', 'register_my_setting' );

注意事项

  • 若计划在 REST API 中使用设置,需同时挂载到 admin_init 和 rest_api_init 钩子,否则 show_in_rest 可能无效。
  • 对于 'array' 类型设置,当 show_in_rest 启用时,必须指定 schema 中的 items 结构,否则会触发 _doing_it_wrong 警告。
  • 避免 sanitize_callback 重复执行:可通过初始化选项(如使用 add_option)或在回调中使用静态变量来检测多次调用。
  • type 和 description 参数仅在 show_in_rest 启用时对 REST API 有效,不影响管理页面或 Options API 的工作方式。

📄 原文内容

Registers a setting and its data.

Parameters

$option_groupstringrequired
A settings group name. Should correspond to an allowed option key name.
Default allowed option key names include 'general', 'discussion', 'media', 'reading', 'writing', and 'options'.
$option_namestringrequired
The name of an option to sanitize and save.
$argsarrayoptional
Data used to describe the setting when registered.

  • type string
    The type of data associated with this setting.
    Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
  • label string
    A label of the data attached to this setting.
  • description string
    A description of the data attached to this setting.
  • sanitize_callback callable
    A callback function that sanitizes the option’s value.
  • show_in_rest bool|array
    Whether data associated with this setting should be included in the REST API.
    When registering complex settings, this argument may optionally be an array with a 'schema' key.
  • default mixed
    Default value when calling get_option().

Default:array()

Source

function register_setting( $option_group, $option_name, $args = array() ) {
	global $new_allowed_options, $wp_registered_settings;

	/*
	 * In 5.5.0, the `$new_whitelist_options` global variable was renamed to `$new_allowed_options`.
	 * Please consider writing more inclusive code.
	 */
	$GLOBALS['new_whitelist_options'] = &$new_allowed_options;

	$defaults = array(
		'type'              => 'string',
		'group'             => $option_group,
		'label'             => '',
		'description'       => '',
		'sanitize_callback' => null,
		'show_in_rest'      => false,
	);

	// Back-compat: old sanitize callback is added.
	if ( is_callable( $args ) ) {
		$args = array(
			'sanitize_callback' => $args,
		);
	}

	/**
	 * Filters the registration arguments when registering a setting.
	 *
	 * @since 4.7.0
	 *
	 * @param array  $args         Array of setting registration arguments.
	 * @param array  $defaults     Array of default arguments.
	 * @param string $option_group Setting group.
	 * @param string $option_name  Setting name.
	 */
	$args = apply_filters( 'register_setting_args', $args, $defaults, $option_group, $option_name );

	$args = wp_parse_args( $args, $defaults );

	// Require an item schema when registering settings with an array type.
	if ( false !== $args['show_in_rest'] && 'array' === $args['type'] && ( ! is_array( $args['show_in_rest'] ) || ! isset( $args['show_in_rest']['schema']['items'] ) ) ) {
		_doing_it_wrong( __FUNCTION__, __( 'When registering an "array" setting to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".' ), '5.4.0' );
	}

	if ( ! is_array( $wp_registered_settings ) ) {
		$wp_registered_settings = array();
	}

	if ( 'misc' === $option_group ) {
		_deprecated_argument(
			__FUNCTION__,
			'3.0.0',
			sprintf(
				/* translators: %s: misc */
				__( 'The "%s" options group has been removed. Use another settings group.' ),
				'misc'
			)
		);
		$option_group = 'general';
	}

	if ( 'privacy' === $option_group ) {
		_deprecated_argument(
			__FUNCTION__,
			'3.5.0',
			sprintf(
				/* translators: %s: privacy */
				__( 'The "%s" options group has been removed. Use another settings group.' ),
				'privacy'
			)
		);
		$option_group = 'reading';
	}

	$new_allowed_options[ $option_group ][] = $option_name;

	if ( ! empty( $args['sanitize_callback'] ) ) {
		add_filter( "sanitize_option_{$option_name}", $args['sanitize_callback'] );
	}
	if ( array_key_exists( 'default', $args ) ) {
		add_filter( "default_option_{$option_name}", 'filter_default_option', 10, 3 );
	}

	/**
	 * Fires immediately before the setting is registered but after its filters are in place.
	 *
	 * @since 5.5.0
	 *
	 * @param string $option_group Setting group.
	 * @param string $option_name  Setting name.
	 * @param array  $args         Array of setting registration arguments.
	 */
	do_action( 'register_setting', $option_group, $option_name, $args );

	$wp_registered_settings[ $option_name ] = $args;
}

Hooks

do_action( ‘register_setting’, string $option_group, string $option_name, array $args )

Fires immediately before the setting is registered but after its filters are in place.

apply_filters( ‘register_setting_args’, array $args, array $defaults, string $option_group, string $option_name )

Filters the registration arguments when registering a setting.

Changelog

Version Description
6.6.0 Added the label argument.
5.5.0 $new_whitelist_options was renamed to $new_allowed_options.
Please consider writing more inclusive code.
4.7.0 $args can be passed to set flags on the setting, similar to register_meta().
3.5.0 The privacy option group was deprecated.
3.0.0 The misc option group was deprecated.
2.7.0 Introduced.

Show 1 moreShow less

User Contributed Notes

  1. Skip to note 12 content

    Some notes about the elements in the $args parameter:

    'type':

    • Only has an effect if 'show_in_rest' is set. So if 'show_in_rest' is false or not part of $args, do not bother with setting a 'type'.
    • Only used by the REST API to define the schema associated with the setting and to implement sanitization over the REST API.
    • Has no effect for the workings of the Admin pages or the way the Setting is handled by the Options API. (I.e.: although probably you shouldn’t, it is possible to submit for example a string value for a setting from the Admin forms that has the 'type' set to "boolean". WP will not complain and will store the value in the options table. It would however cause issues with the REST API, so be careful!)
    • On top of those listed in this page, it also accepts values such as: 'array' and 'object'.

    'description':

    • Only has an effect if 'show_in_rest' is set. So if 'show_in_rest' is false or not part of $args, do not bother with setting a 'description'.
    • Only used by the REST API.

    'default':

    • Affects both the Options API (e.g. get_option()) and the REST API.

    In conclusion: if you do not plan to include your setting in the REST API, it is perfectly enough to only set the 'default' and the 'sanitize_callback' elements in the $args array. Anything else would be ignored anyway.

  2. Skip to note 13 content

    /**
    * Registers a text field setting for WordPress 4.7 and higher.
    **/
    function register_my_setting() {
    	$args = array(
    			'type' => 'string', 
    			'sanitize_callback' => 'sanitize_text_field',
    			'default' => NULL,
    			);
        register_setting( 'my_options_group', 'my_option_name', $args ); 
    } 
    add_action( 'admin_init', 'register_my_setting' );

  3. Skip to note 14 content

    The sanitize callback will be launched twice! Therefore, if sanitizing involves any performance critical or singular tasks, then measures must be taken in the callback to avoid duplicate execution of those portions.

    const	PLUGIN_SLUG =	'MyPlugin';
    
    /*
     *	Setup Plug-In Hooks (Namespaced Example)
     */
    add_action( 'wp_loaded', __NAMESPACE__.'on_wp_loaded' );
    
    if ( is_blog_admin() ) {
    	register_activation_hook( __FILE__,  __NAMESPACE__.'on_activate' );
    	register_deactivation_hook( __FILE__,  __NAMESPACE__.'on_deactivate' );
    	
    	add_action( 'admin_menu', __NAMESPACE__.'on_admin_menu' );
    	add_action( 'admin_init', __NAMESPACE__.'on_admin_init' );
    	add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), __NAMESPACE__.'action_links' );
    }
    return;
    
    /*
     *	Add custom options to whitelist, allowing valiated settings to be saved by form.
     */
    function on_admin_init(): void 
    {
    	register_setting( PLUGIN_SLUG, PLUGIN_SLUG, [ 'sanitize_callback' => __NAMESPACE__.'sanitize_settings' ] ); 
    }
    
    /*
     *	Sanitize the form input.
     */
    function sanitize_settings( $input = NULL ):  
    {
    	// Detect multiple sanitizing passes.
    	// Accomodates bug: <a href="https://core.trac.wordpress.org/ticket/21989" rel="nofollow ugc">https://core.trac.wordpress.org/ticket/21989</a>
    	static $pass_count = 0; $pass_count++;
    
    	if ( $pass_count <= 1 ) {
    		// Handle any single-time / performane sensitive actions.
    
    	}
    
    	// Insert regular santizing code here.
    }

  4. Skip to note 17 content

    If you want the setting to appear in the wp-json/wp/v2/settings endpoint, you’ll need to call register_setting() on the rest_api_init action, in addition to the normal admin_init action.

    add_action( 'admin_init',    'foo_register_settings' );
    add_action( 'rest_api_init', 'foo_register_settings' );
    
    function foo_register_settings() {
    	register_setting(
    		'foo',
    		'foo_my_setting',
    		array(
    			'type'              => 'string',
    			'show_in_rest'      => true,
    			'sanitize_callback' => 'sanitize_text_field',
    		)
    	);
    }

  5. Skip to note 18 content

    Notice that the sanitization_callback of all the registered settings that share the same $option_group will be executed when saving that option group.

    This sounds obvious, but notice that it will also happen even when the settings that belong to this group are not present in the current page but in a different one.

    For example if we have the following option pages and settings:

    admin.php?page=settings_page_1 containing the optionA form
    admin.php?page=settings_page_2 containing the optionB form

    Where each setting has been registered with their own register_setting() in different files and being output in different pages but the same $option_group string has been used for both of them.

    Saving the page admin.php?page=settings_page_1 will not only trigger the sanitization_callback from optionA, but also the sanitization_callback from optionB.

  6. Skip to note 19 content

    An example of array settings. if you want to save an array in settings and also show the array setting to appear in the wp-json/wp/v2/settings endpoint, then you have to register show_in_rest schema.

    add_action( 'admin_init',    'wpdocs_foo_register_settings' );
    add_action( 'rest_api_init', 'wpdocs_foo_register_settings' );
    function wpdocs_foo_register_settings() {
    	register_setting( 'general_setting', 'id' );
    	register_setting( 'general_setting', 'order' );
    	register_setting(
    		'general_setting',
    		'slider-data',
    		array(
    			'show_in_rest' => array(
    				'name' => 'images_slide',
    				'schema' => array(
    					'type'  => 'array',
    					'items' => array(
    						'id'    => 'string',
    						'order' => 'string',
    					),
    				),
    			),
    			'type' => 'array',
    			'sanitize_callback' => array( $this, 'wpdocs_admin_post_save_data' ),
    		)
    	);
    }

  7. Skip to note 20 content

    Example for object and array types:

    register_setting(
    	'dp_example_settings_group',
    	'dp_example_array_settings',
    	array(
    		'type'         => 'object',
    		'default'      => array(
    			'A',
    			'B',
    			'C',
    		),
    		'show_in_rest' => array(
    			'schema' => array(
    				'type'  => 'object',
    				'items' => array(
    					'type' => 'string',
    				),
    			),
    		),
    	)
    );
    
    register_setting(
    	'dp_example_settings_group',
    	'dp_example_object_settings',
    	array(
    		'type'         => 'object',
    		'default'      => array(
    			'some_str' => 'A',
    			'some_int' => 3,
    		),
    		'show_in_rest' => array(
    			'schema' => array(
    				'type'       => 'object',
    				'properties' => array(
    					'some_str' => array(
    						'type' => 'string',
    					),
    					'some_int' => array(
    						'type' => 'integer',
    					),
    				),
    			),
    		),
    	)
    );

  8. Skip to note 21 content

    // Registering the field
    function wpdocs_add_option_field_to_general_admin_page() {
    
    	register_setting( 'general', 'Field_Name_To_Add' );
    
    	add_settings_field( 
    		'field_id-to-add', 
    		'Field Name To Display', 
    		'wpdocs_setting_callback_function', //Function to Call
    		'general', 
    		'default', 
    		array( 
    			'id' => 'field_id-to-add', 
    			'option_name' => 'Field_Name_To_Add' 
    		)
    	);
    }
    
    // Adding options to registered field
    add_action( 'admin_menu', 'wpdocs_add_option_field_to_general_admin_page' ); // CallBack Function
    
    function wpdocs_setting_callback_function( $val ) {
    	$id = $val['id'];
    	$option_name = $val['option_name'];
    	?>
    	<input 
    		type="tel" //this can be any HTML input type: date, number, text etc.
    		name="<?php echo esc_attr( $option_name ) ?>"
    		id="<?php echo esc_attr( $id ) ?>" 
    		value="<?php echo esc_attr( get_option( $option_name ) ) ?>" // Displays the value stored in DB
    	/> 
    	</pre>
    				</div><!-- .comment-content -->
    
    					<section id='feedback-5349' class='wporg-has-embedded-code feedback hide-if-js' data-comment-count='0'>
    </section><!-- .feedback -->
    <footer class='feedback-links wporg-dot-link-list' >
    <a role="button" class="feedback-login" href="https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fregister_setting%2F%3Freplytocom%3D5349%23feedback-editor-5349" rel="nofollow">Log in to add feedback</a></footer>
    </article><!-- .comment-body -->
    </li>
    			<li id="comment-7180" data-comment-id="7180" class="comment byuser comment-author-iuriem odd alt thread-odd thread-alt depth-1">
    			<article id="div-comment-7180" class="comment-body">
    
    							<a href="#comment-content-7180" class="screen-reader-text">Skip to note 22 content</a>
    				<header class="comment-meta">
    					<div class="comment-author vcard">
    						<span class="comment-author-attribution">
    						<a href="https://profiles.wordpress.org/iuriem/" rel="external nofollow" class="url">Tunn</a>						</span>
    						<a class="comment-date" href="https://developer.wordpress.org/reference/functions/register_setting/#comment-7180">
    							<time datetime="2024-10-14T12:15:25+00:00">
    							2 years ago							</time>
    						</a>
    
    																													</div>
    					<div class="user-note-voting" data-nonce="04578f482c" data-can-vote="false"><a class="user-note-voting-up" title="You must log in to vote on the helpfulness of this note" data-id="7180" data-vote="up" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fregister_setting%2F%23comment-7180"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a><span class="user-note-voting-count " title=""><span class="screen-reader-text">Vote results for this note: </span>0</span><a class="user-note-voting-down" title="You must log in to vote on the helpfulness of this note" data-id="7180" data-vote="down" href="https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fregister_setting%2F%23comment-7180"><span class="screen-reader-text">You must log in to vote on the helpfulness of this note</span></a></div>				</header>
    				<!-- .comment-metadata -->
    			
    				<div class="wporg-has-embedded-code comment-content" id="comment-content-7180">
    				<p><strong>Avoid duplicate execution of sanitizing callback!!!</strong></p>
    <p>What to do (two steps):</p>
    <p>1. Initialize your setting before to register it.</p>
    <pre class="wp-block-code"><code lang="php" class="language-php line-numbers">// Example for a plugin.
    function activate_my_plugin() {
        add_option( "my-option", "", "", false );
    }
    register_activation_hook( __FILE__, "activate_my_plugin" );

    2. Register the setting a) without the “default” parameter OR b) with the not-empty “default” parameter (so, not “” and not []).