函数文档

wp_check_comment_flood()

💡 云策文档标注

概述

wp_check_comment_flood() 函数用于检测评论是否发生洪水攻击(即短时间内大量评论)。该函数不会对具有管理或审核权限的用户执行检查,以避免阻塞管理员操作。

关键要点

  • 函数检查评论是否在短时间内频繁发布,基于IP地址、邮箱和最近一小时内的评论记录。
  • 如果检测到洪水攻击,默认会调用 wp_die() 终止执行并显示错误消息,但可通过 $avoid_die 参数控制行为。
  • 支持多个过滤器(如 comment_flood_filter 和 comment_flood_message)和动作(如 comment_flood_trigger)来自定义洪水检测逻辑和错误消息。
  • 函数返回布尔值,表示是否发生评论洪水攻击。

代码示例

function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) {
    global $wpdb;

    // Another callback has declared a flood. Trust it.
    if ( true === $is_flood ) {
        return $is_flood;
    }

    // Don't throttle admins or moderators.
    if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) {
        return false;
    }

    $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS );

    if ( is_user_logged_in() ) {
        $user         = get_current_user_id();
        $check_column = '`user_id`';
    } else {
        $user         = $ip;
        $check_column = '`comment_author_IP`';
    }

    $sql = $wpdb->prepare(
        "SELECT `comment_date_gmt` FROM `$wpdb->comments` WHERE `comment_date_gmt` >= %s AND ( $check_column = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1",
        $hour_ago,
        $user,
        $email
    );

    $lasttime = $wpdb->get_var( $sql );

    if ( $lasttime ) {
        $time_lastcomment = mysql2date( 'U', $lasttime, false );
        $time_newcomment  = mysql2date( 'U', $date, false );

        $flood_die = apply_filters( 'comment_flood_filter', false, $time_lastcomment, $time_newcomment );

        if ( $flood_die ) {
            do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment );

            if ( $avoid_die ) {
                return true;
            } else {
                $comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) );

                if ( wp_doing_ajax() ) {
                    die( $comment_flood_message );
                }

                wp_die( $comment_flood_message, 429 );
            }
        }
    }

    return false;
}

注意事项

  • 函数参数包括 $is_flood(布尔值,表示是否已检测到洪水)、$ip(评论者IP地址)、$email(评论者邮箱)、$date(MySQL时间字符串)和 $avoid_die(可选布尔值,控制是否避免调用 wp_die())。
  • 使用 wp_die() 时,可以传递额外参数如响应码、链接等来控制错误页面的行为。
  • 函数依赖于 WordPress 数据库操作和用户权限检查,确保在适当的环境下调用。

📄 原文内容

Checks whether comment flooding is occurring.

Description

Won’t run, if current user can manage options, so to not block administrators.

Parameters

$is_floodboolrequired
Is a comment flooding occurring?
$ipstringrequired
Comment author’s IP address.
$emailstringrequired
Comment author’s email address.
$datestringrequired
MySQL time string.
$avoid_diebooloptional
When true, a disallowed comment will result in the function returning without executing wp_die() or die().

More Arguments from wp_die( … $args )

Arguments to control behavior. If $args is an integer, then it is treated as the response code.

  • response int
    The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
  • link_url string
    A URL to include a link to. Only works in combination with $link_text.
  • link_text string
    A label for the link to include. Only works in combination with $link_url.
  • back_link bool
    Whether to include a link to go back. Default false.
  • text_direction string
    The text direction. This is only useful internally, when WordPress is still loading and the site’s locale is not set up yet. Accepts 'rtl' and 'ltr'.
    Default is the value of is_rtl() .
  • charset string
    Character set of the HTML output. Default 'utf-8'.
  • code string
    Error code to use. Default is 'wp_die', or the main error code if $message is a WP_Error.
  • exit bool
    Whether to exit the process after completion. Default true.

Default:false

Return

bool Whether comment flooding is occurring.

Source

function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) {
	global $wpdb;

	// Another callback has declared a flood. Trust it.
	if ( true === $is_flood ) {
		return $is_flood;
	}

	// Don't throttle admins or moderators.
	if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) {
		return false;
	}

	$hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS );

	if ( is_user_logged_in() ) {
		$user         = get_current_user_id();
		$check_column = '`user_id`';
	} else {
		$user         = $ip;
		$check_column = '`comment_author_IP`';
	}

	$sql = $wpdb->prepare(
		"SELECT `comment_date_gmt` FROM `$wpdb->comments` WHERE `comment_date_gmt` >= %s AND ( $check_column = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1",
		$hour_ago,
		$user,
		$email
	);

	$lasttime = $wpdb->get_var( $sql );

	if ( $lasttime ) {
		$time_lastcomment = mysql2date( 'U', $lasttime, false );
		$time_newcomment  = mysql2date( 'U', $date, false );

		/**
		 * Filters the comment flood status.
		 *
		 * @since 2.1.0
		 *
		 * @param bool $bool             Whether a comment flood is occurring. Default false.
		 * @param int  $time_lastcomment Timestamp of when the last comment was posted.
		 * @param int  $time_newcomment  Timestamp of when the new comment was posted.
		 */
		$flood_die = apply_filters( 'comment_flood_filter', false, $time_lastcomment, $time_newcomment );

		if ( $flood_die ) {
			/**
			 * Fires before the comment flood message is triggered.
			 *
			 * @since 1.5.0
			 *
			 * @param int $time_lastcomment Timestamp of when the last comment was posted.
			 * @param int $time_newcomment  Timestamp of when the new comment was posted.
			 */
			do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment );

			if ( $avoid_die ) {
				return true;
			} else {
				/**
				 * Filters the comment flood error message.
				 *
				 * @since 5.2.0
				 *
				 * @param string $comment_flood_message Comment flood error message.
				 */
				$comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) );

				if ( wp_doing_ajax() ) {
					die( $comment_flood_message );
				}

				wp_die( $comment_flood_message, 429 );
			}
		}
	}

	return false;
}

Hooks

apply_filters( ‘comment_flood_filter’, bool $bool, int $time_lastcomment, int $time_newcomment )

Filters the comment flood status.

apply_filters( ‘comment_flood_message’, string $comment_flood_message )

Filters the comment flood error message.

do_action( ‘comment_flood_trigger’, int $time_lastcomment, int $time_newcomment )

Fires before the comment flood message is triggered.

Changelog

Version Description
4.7.0 Introduced.