函数文档

sanitize_post_field()

💡 云策文档标注

概述

sanitize_post_field() 函数用于根据上下文对文章字段进行清理,确保数据安全。它支持多种上下文(如 'raw'、'edit'、'db'、'display'、'attribute' 和 'js'),默认使用 'display',并调用相应的过滤器进行值处理。

关键要点

  • 函数参数包括字段名、值、文章ID和上下文,上下文默认为 'display'。
  • 根据上下文调用不同的 apply_filters() 钩子,例如 'edit' 上下文触发 edit_{$field} 和 {$field_no_prefix}_edit_pre 过滤器。
  • 对整数字段(如 ID、post_parent)进行类型转换,对数组字段(如 ancestors)进行整数映射。
  • 在 'edit' 上下文中,特定字段(如 post_content)使用 format_to_edit() 处理,其他字段使用 esc_attr() 转义。
  • 在 'db' 上下文中,调用 pre_{$field} 或 {$field}_pre 等过滤器进行保存前处理。
  • 在 'display'、'attribute' 或 'js' 上下文中,调用 {$field} 或 post_{$field} 过滤器,并根据上下文使用 esc_attr() 或 esc_js() 转义。

代码示例

// 清理文章标题用于显示
$post = get_post( 35 );
$post_title = sanitize_post_field( 'post_title', $post->post_title, $post->ID, 'display' );
echo $post_title;

// 清理文章标题用于属性(如隐藏表单字段)
$post = get_post( 543 );
$post_title = sanitize_post_field( 'post_title', $post->post_title, $post->ID, 'attribute' );
echo '<input type="hidden" value="' . $post_title . '">';

注意事项

  • 上下文 'attribute' 和 'js' 在调用过滤器时被当作 'display' 处理,但后续会分别应用 esc_attr() 和 esc_js() 转义。
  • 函数自 WordPress 2.3.0 引入,4.4.0 版本后 $context 默认值改为 'display'。
  • 字段名区分大小写,常见字段包括 ID、post_author、post_content 等。

📄 原文内容

Sanitizes a post field based on context.

Description

Possible context values are: ‘raw’, ‘edit’, ‘db’, ‘display’, ‘attribute’ and ‘js’. The ‘display’ context is used by default. ‘attribute’ and ‘js’ contexts are treated like ‘display’ when calling filters.

Parameters

$fieldstringrequired
The Post Object field name.
$valuemixedrequired
The Post Object value.
$post_idintrequired
Post ID.
$contextstringoptional
How to sanitize the field. Possible values are 'raw', 'edit', 'db', 'display', 'attribute' and 'js'. Default 'display'.

Return

mixed Sanitized value.

More Information

Uses apply_filters():

  • Calls 'edit_{$field}' and '{$field_no_prefix}_edit_pre' passing $value and $post_id if $context is 'edit' and field name prefix is 'post_'.
  • Calls 'edit_post_{$field}' passing $value and $post_id if $context is 'db'.
  • Calls 'pre_{$field}' passing $value if $context is 'db' and field name prefix is 'post_'.
  • Calls '{$field}_pre' passing $value if $context is 'db' and field name prefix is not 'post_'.
  • Calls '{$field}' passing $value, $post_id and $context if $context is anything other than 'raw', 'edit' and 'db' and field name prefix is 'post_'.
  • Calls 'post_$field' passing $value if $context is anything other than 'raw', 'edit' and 'db' and field name prefix is not 'post_'.

Source

function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
	$int_fields = array( 'ID', 'post_parent', 'menu_order' );
	if ( in_array( $field, $int_fields, true ) ) {
		$value = (int) $value;
	}

	// Fields which contain arrays of integers.
	$array_int_fields = array( 'ancestors' );
	if ( in_array( $field, $array_int_fields, true ) ) {
		$value = array_map( 'absint', $value );
		return $value;
	}

	if ( 'raw' === $context ) {
		return $value;
	}

	$prefixed = false;
	if ( str_contains( $field, 'post_' ) ) {
		$prefixed        = true;
		$field_no_prefix = str_replace( 'post_', '', $field );
	}

	if ( 'edit' === $context ) {
		$format_to_edit = array( 'post_content', 'post_excerpt', 'post_title', 'post_password' );

		if ( $prefixed ) {

			/**
			 * Filters the value of a specific post field to edit.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the post
			 * field name. Possible filter names include:
			 *
			 *  - `edit_post_author`
			 *  - `edit_post_date`
			 *  - `edit_post_date_gmt`
			 *  - `edit_post_content`
			 *  - `edit_post_title`
			 *  - `edit_post_excerpt`
			 *  - `edit_post_status`
			 *  - `edit_post_password`
			 *  - `edit_post_name`
			 *  - `edit_post_modified`
			 *  - `edit_post_modified_gmt`
			 *  - `edit_post_content_filtered`
			 *  - `edit_post_parent`
			 *  - `edit_post_type`
			 *  - `edit_post_mime_type`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value   Value of the post field.
			 * @param int   $post_id Post ID.
			 */
			$value = apply_filters( "edit_{$field}", $value, $post_id );

			/**
			 * Filters the value of a specific post field to edit.
			 *
			 * Only applied to post fields with a name which is prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
			 * post field name minus the `post_` prefix. Possible filter names include:
			 *
			 *  - `author_edit_pre`
			 *  - `date_edit_pre`
			 *  - `date_gmt_edit_pre`
			 *  - `content_edit_pre`
			 *  - `title_edit_pre`
			 *  - `excerpt_edit_pre`
			 *  - `status_edit_pre`
			 *  - `password_edit_pre`
			 *  - `name_edit_pre`
			 *  - `modified_edit_pre`
			 *  - `modified_gmt_edit_pre`
			 *  - `content_filtered_edit_pre`
			 *  - `parent_edit_pre`
			 *  - `type_edit_pre`
			 *  - `mime_type_edit_pre`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value   Value of the post field.
			 * @param int   $post_id Post ID.
			 */
			$value = apply_filters( "{$field_no_prefix}_edit_pre", $value, $post_id );
		} else {
			/**
			 * Filters the value of a specific post field to edit.
			 *
			 * Only applied to post fields not prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the
			 * post field name. Possible filter names include:
			 *
			 *  - `edit_post_ID`
			 *  - `edit_post_ping_status`
			 *  - `edit_post_pinged`
			 *  - `edit_post_to_ping`
			 *  - `edit_post_comment_count`
			 *  - `edit_post_comment_status`
			 *  - `edit_post_guid`
			 *  - `edit_post_menu_order`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value   Value of the post field.
			 * @param int   $post_id Post ID.
			 */
			$value = apply_filters( "edit_post_{$field}", $value, $post_id );
		}

		if ( in_array( $field, $format_to_edit, true ) ) {
			if ( 'post_content' === $field ) {
				$value = format_to_edit( $value, user_can_richedit() );
			} else {
				$value = format_to_edit( $value );
			}
		} else {
			$value = esc_attr( $value );
		}
	} elseif ( 'db' === $context ) {
		if ( $prefixed ) {

			/**
			 * Filters the value of a specific post field before saving.
			 *
			 * Only applied to post fields with a name which is prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the post
			 * field name. Possible filter names include:
			 *
			 *  - `pre_post_author`
			 *  - `pre_post_date`
			 *  - `pre_post_date_gmt`
			 *  - `pre_post_content`
			 *  - `pre_post_title`
			 *  - `pre_post_excerpt`
			 *  - `pre_post_status`
			 *  - `pre_post_password`
			 *  - `pre_post_name`
			 *  - `pre_post_modified`
			 *  - `pre_post_modified_gmt`
			 *  - `pre_post_content_filtered`
			 *  - `pre_post_parent`
			 *  - `pre_post_type`
			 *  - `pre_post_mime_type`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value Value of the post field.
			 */
			$value = apply_filters( "pre_{$field}", $value );

			/**
			 * Filters the value of a specific field before saving.
			 *
			 * Only applied to post fields with a name which is prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
			 * post field name minus the `post_` prefix. Possible filter names include:
			 *
			 *  - `author_save_pre`
			 *  - `date_save_pre`
			 *  - `date_gmt_save_pre`
			 *  - `content_save_pre`
			 *  - `title_save_pre`
			 *  - `excerpt_save_pre`
			 *  - `status_save_pre`
			 *  - `password_save_pre`
			 *  - `name_save_pre`
			 *  - `modified_save_pre`
			 *  - `modified_gmt_save_pre`
			 *  - `content_filtered_save_pre`
			 *  - `parent_save_pre`
			 *  - `type_save_pre`
			 *  - `mime_type_save_pre`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value Value of the post field.
			 */
			$value = apply_filters( "{$field_no_prefix}_save_pre", $value );
		} else {
			/**
			 * Filters the value of a specific field before saving.
			 *
			 * Only applied to post fields with a name which is prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
			 * post field name minus the `post_` prefix. Possible filter names include:
			 *
			 *  - `pre_post_ID`
			 *  - `pre_post_comment_status`
			 *  - `pre_post_ping_status`
			 *  - `pre_post_to_ping`
			 *  - `pre_post_pinged`
			 *  - `pre_post_guid`
			 *  - `pre_post_menu_order`
			 *  - `pre_post_comment_count`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value Value of the post field.
			 */
			$value = apply_filters( "pre_post_{$field}", $value );

			/**
			 * Filters the value of a specific post field before saving.
			 *
			 * Only applied to post fields with a name which is *not* prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the post
			 * field name. Possible filter names include:
			 *
			 *  - `ID_pre`
			 *  - `comment_status_pre`
			 *  - `ping_status_pre`
			 *  - `to_ping_pre`
			 *  - `pinged_pre`
			 *  - `guid_pre`
			 *  - `menu_order_pre`
			 *  - `comment_count_pre`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed $value Value of the post field.
			 */
			$value = apply_filters( "{$field}_pre", $value );
		}
	} else {

		// Use display filters by default.
		if ( $prefixed ) {

			/**
			 * Filters the value of a specific post field for display.
			 *
			 * Only applied to post fields with a name which is prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the post
			 * field name. Possible filter names include:
			 *
			 *  - `post_author`
			 *  - `post_date`
			 *  - `post_date_gmt`
			 *  - `post_content`
			 *  - `post_title`
			 *  - `post_excerpt`
			 *  - `post_status`
			 *  - `post_password`
			 *  - `post_name`
			 *  - `post_modified`
			 *  - `post_modified_gmt`
			 *  - `post_content_filtered`
			 *  - `post_parent`
			 *  - `post_type`
			 *  - `post_mime_type`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed  $value   Value of the prefixed post field.
			 * @param int    $post_id Post ID.
			 * @param string $context Context for how to sanitize the field.
			 *                        Accepts 'raw', 'edit', 'db', 'display',
			 *                        'attribute', or 'js'. Default 'display'.
			 */
			$value = apply_filters( "{$field}", $value, $post_id, $context );
		} else {
			/**
			 * Filters the value of a specific post field for display.
			 *
			 * Only applied to post fields name which is *not* prefixed with `post_`.
			 *
			 * The dynamic portion of the hook name, `$field`, refers to the post
			 * field name. Possible filter names include:
			 *
			 *  - `post_ID`
			 *  - `post_comment_status`
			 *  - `post_ping_status`
			 *  - `post_to_ping`
			 *  - `post_pinged`
			 *  - `post_guid`
			 *  - `post_menu_order`
			 *  - `post_comment_count`
			 *
			 * @since 2.3.0
			 *
			 * @param mixed  $value   Value of the unprefixed post field.
			 * @param int    $post_id Post ID
			 * @param string $context Context for how to sanitize the field.
			 *                        Accepts 'raw', 'edit', 'db', 'display',
			 *                        'attribute', or 'js'. Default 'display'.
			 */
			$value = apply_filters( "post_{$field}", $value, $post_id, $context );
		}

		if ( 'attribute' === $context ) {
			$value = esc_attr( $value );
		} elseif ( 'js' === $context ) {
			$value = esc_js( $value );
		}
	}

	// Restore the type for integer fields after esc_attr().
	if ( in_array( $field, $int_fields, true ) ) {
		$value = (int) $value;
	}
	return $value;
}

Hooks

apply_filters( “edit_post_{$field}”, mixed $value, int $post_id )

Filters the value of a specific post field to edit.

apply_filters( “edit_{$field}”, mixed $value, int $post_id )

Filters the value of a specific post field to edit.

apply_filters( “post_{$field}”, mixed $value, int $post_id, string $context )

Filters the value of a specific post field for display.

apply_filters( “pre_post_{$field}”, mixed $value )

Filters the value of a specific field before saving.

apply_filters( “pre_{$field}”, mixed $value )

Filters the value of a specific post field before saving.

apply_filters( “{$field_no_prefix}_edit_pre”, mixed $value, int $post_id )

Filters the value of a specific post field to edit.

apply_filters( “{$field_no_prefix}_save_pre”, mixed $value )

Filters the value of a specific field before saving.

apply_filters( “{$field}”, mixed $value, int $post_id, string $context )

Filters the value of a specific post field for display.

apply_filters( “{$field}_pre”, mixed $value )

Filters the value of a specific post field before saving.

Changelog

Version Description
4.4.0 Like sanitize_post(), $context defaults to 'display'.
2.3.0 Introduced.

User Contributed Notes

  1. Skip to note 5 content

    Sanitizing for Attributes
    Sanitize a post title for use as the value of a hidden form field:

    $post = get_post( 543 );
    $post_title = sanitize_post_field( 'post_title', $post->post_title, $post->ID, 'attribute' );
    echo '<input type="hidden" name="post-title" value="' . esc_attr( $post_title ) . '" />';

  2. Skip to note 6 content

    Here are the default post fields that you can get (case-sensitive):

      ID
      post_author
      post_date
      post_date_gmt
      post_content
      post_title
      post_excerpt
      post_status
      comment_status
      ping_status
      post_password
      post_name
      to_ping
      pinged
      post_modified
      post_modified_gmt
      post_content_filtered
      post_parent
      guid
      menu_order
      post_type
      post_mime_type
      comment_count
      filter