解释 `wp_get_current_commenter()` 函数的源码,它是如何从 `Cookie` 或 `GET`/`POST` 请求中获取评论者信息的?

嘿,大家好! 今天咱们来聊聊 WordPress 里面一个挺重要的小家伙儿:wp_get_current_commenter()。 这玩意儿,听名字就知道,是用来获取当前评论者的信息的。 但它具体是怎么工作的呢? 别急,咱们一点点扒开它的源码,看看里面到底藏着什么秘密。

第一幕:源码探秘,拨开迷雾

首先,咱们先找到 wp_get_current_commenter() 函数的真身。 它通常位于 WordPress 核心代码的 wp-includes/comment.php 文件中。

function wp_get_current_commenter() {
    static $current_commenter = null;

    if ( null !== $current_commenter ) {
        return $current_commenter;
    }

    $comment_author       = '';
    $comment_author_email = '';
    $comment_author_url   = '';

    if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) {
        $comment_author = wp_slash( $_COOKIE['comment_author_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author = $user->display_name;
    }

    if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) {
        $comment_author_email = wp_slash( $_COOKIE['comment_author_email_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author_email = $user->user_email;
    }

    if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) {
        $comment_author_url = wp_slash( $_COOKIE['comment_author_url_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author_url = get_author_posts_url( $user->ID );
    }

    $current_commenter = (object) array(
        'comment_author'       => $comment_author,
        'comment_author_email' => $comment_author_email,
        'comment_author_url'   => $comment_author_url,
    );

    /**
     * Filters the current commenter data.
     *
     * @since 2.8.0
     *
     * @param object $current_commenter The current commenter object.
     */
    $current_commenter = apply_filters( 'wp_get_current_commenter', $current_commenter );

    return $current_commenter;
}

第二幕:逐行解读,揭秘流程

咱们来一行一行地拆解这段代码,看看它是怎么工作的:

  1. 静态变量缓存:

    static $current_commenter = null;
    
    if ( null !== $current_commenter ) {
        return $current_commenter;
    }

    这段代码使用了静态变量 $current_commenter 来缓存结果。 也就是说,如果之前已经获取过评论者信息,下次再调用这个函数,直接返回缓存的结果,避免重复计算。 这就像咱们平时做饭,如果昨天已经炒了一盘土豆丝,今天就不用再从削土豆皮开始了,直接拿出来热热就行。

  2. 初始化变量:

    $comment_author       = '';
    $comment_author_email = '';
    $comment_author_url   = '';

    这里先定义了三个变量,分别用来存储评论者的姓名、邮箱和网址。 默认值都是空字符串。 就像咱们要盖房子,先得把地基打好,这些变量就是地基。

  3. 从 Cookie 中获取信息:

    if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) {
        $comment_author = wp_slash( $_COOKIE['comment_author_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author = $user->display_name;
    }
    
    if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) {
        $comment_author_email = wp_slash( $_COOKIE['comment_author_email_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author_email = $user->user_email;
    }
    
    if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) {
        $comment_author_url = wp_slash( $_COOKIE['comment_author_url_' . COOKIEHASH] );
    } else if ( is_user_logged_in() ) {
        $user = wp_get_current_user();
        $comment_author_url = get_author_posts_url( $user->ID );
    }

    这段代码是核心部分。 它首先检查浏览器中是否存在特定的 Cookie。 这些 Cookie 的名称分别是 comment_author_comment_author_email_comment_author_url_,后面都跟着一个 COOKIEHASHCOOKIEHASH 是 WordPress 用来增加 Cookie 安全性的一个哈希值。

    • 如果找到了这些 Cookie,就使用 wp_slash() 函数对 Cookie 的值进行处理,并将结果赋值给对应的变量。 wp_slash() 函数主要用于转义 Cookie 值中的反斜杠,防止出现安全问题。
    • 如果未找到 Cookie,则检查用户是否已登录。 如果用户已登录,则从当前用户对象 ($user) 中获取评论者的姓名 (display_name)、邮箱 (user_email) 和个人网站链接 (get_author_posts_url)。

    简而言之,这段代码优先从 Cookie 中获取评论者信息,如果 Cookie 不存在,则尝试从已登录用户的资料中获取。

  4. 创建评论者对象:

    $current_commenter = (object) array(
        'comment_author'       => $comment_author,
        'comment_author_email' => $comment_author_email,
        'comment_author_url'   => $comment_author_url,
    );

    这里将前面获取到的姓名、邮箱和网址,封装成一个对象。 这个对象就是最终返回的评论者信息。

  5. 应用过滤器:

    /**
     * Filters the current commenter data.
     *
     * @since 2.8.0
     *
     * @param object $current_commenter The current commenter object.
     */
    $current_commenter = apply_filters( 'wp_get_current_commenter', $current_commenter );

    这段代码使用 apply_filters() 函数,允许开发者通过 wp_get_current_commenter 过滤器,修改评论者对象。 这是一个很强大的功能,可以让我们自定义评论者信息的获取方式。

  6. 返回结果:

    return $current_commenter;

    最后,函数返回封装好的评论者对象。

第三幕:Cookie 的秘密,追踪足迹

现在,咱们来深入了解一下 Cookie 在这个过程中的作用。 当用户在评论表单中填写姓名、邮箱和网址并提交评论时,WordPress 会将这些信息保存到 Cookie 中。 这样,下次用户再次访问网站并发表评论时,就不需要重新填写这些信息了。

Cookie 的名称格式如下:

Cookie 名称 存储的信息
comment_author_[COOKIEHASH] 评论者姓名
comment_author_email_[COOKIEHASH] 评论者邮箱
comment_author_url_[COOKIEHASH] 评论者网址

COOKIEHASH 是一个随机字符串,可以增强 Cookie 的安全性,防止被恶意篡改。

第四幕:GET/POST 请求,幕后英雄

虽然 wp_get_current_commenter() 函数本身不直接从 GET 或 POST 请求中获取数据,但它所依赖的 Cookie,实际上是可以通过 POST 请求来设置的。

当用户提交评论表单时,表单中的姓名、邮箱和网址等信息会通过 POST 请求发送到服务器。 WordPress 接收到这些信息后,会将它们保存到 Cookie 中。

因此,可以说 GET/POST 请求是 wp_get_current_commenter() 函数的幕后英雄。 没有 POST 请求,就没有 Cookie,也就没有评论者信息。

第五幕:实战演练,灵活应用

咱们来举几个例子,看看 wp_get_current_commenter() 函数在实际开发中可以怎么用:

  1. 自定义评论表单:

    假设我们需要在评论表单中添加一些额外的字段,例如用户所在城市。 我们可以使用 wp_get_current_commenter 过滤器,将这些字段的值添加到评论者对象中。

    add_filter( 'wp_get_current_commenter', 'my_custom_commenter_data' );
    
    function my_custom_commenter_data( $commenter ) {
        if ( isset( $_POST['comment_city'] ) ) {
            $commenter->comment_city = sanitize_text_field( $_POST['comment_city'] );
        }
    
        return $commenter;
    }

    这段代码首先定义了一个名为 my_custom_commenter_data 的函数,然后使用 add_filter() 函数将这个函数添加到 wp_get_current_commenter 过滤器中。

    my_custom_commenter_data 函数中,我们首先检查 POST 请求中是否存在 comment_city 字段。 如果存在,就使用 sanitize_text_field() 函数对这个字段的值进行过滤,然后将结果添加到评论者对象中。

  2. 显示评论者信息:

    我们可以使用 wp_get_current_commenter() 函数,在主题中显示当前评论者的信息。

    <?php
    $commenter = wp_get_current_commenter();
    echo '欢迎回来,' . esc_html( $commenter->comment_author ) . '!';
    ?>

    这段代码首先调用 wp_get_current_commenter() 函数,获取评论者对象。 然后,使用 esc_html() 函数对评论者的姓名进行转义,防止 XSS 攻击。 最后,将姓名显示在页面上。

第六幕:总结,提炼精华

wp_get_current_commenter() 函数是 WordPress 中一个非常实用的函数,它可以帮助我们获取当前评论者的信息。 它主要通过以下方式获取信息:

  • 优先从 Cookie 中获取: 如果浏览器中存在 comment_author_comment_author_email_comment_author_url_ 等 Cookie,就从这些 Cookie 中获取信息。
  • 如果 Cookie 不存在,则尝试从已登录用户的资料中获取: 如果用户已登录,就从当前用户对象中获取信息。
  • 允许开发者通过过滤器自定义评论者信息的获取方式: 开发者可以使用 wp_get_current_commenter 过滤器,修改评论者对象。

虽然 wp_get_current_commenter() 函数本身不直接从 GET 或 POST 请求中获取数据,但它所依赖的 Cookie,实际上是通过 POST 请求来设置的。

获取方式 优先级 数据来源
Cookie $_COOKIE['comment_author_' . COOKIEHASH] , $_COOKIE['comment_author_email_' . COOKIEHASH], $_COOKIE['comment_author_url_' . COOKIEHASH]
已登录用户 通过 wp_get_current_user() 获取的用户对象,使用 display_nameuser_emailget_author_posts_url
GET/POST 请求 间接影响,评论表单通过 POST 请求发送数据,服务器将数据存储到 Cookie 中。 wp_get_current_commenter() 函数本身不直接处理 GET/POST 请求,但 Cookie 的设置依赖于 POST 请求。 通过 wp_get_current_commenter 过滤器可以从 POST 请求中获取额外的数据。
自定义过滤器 最高 可以完全自定义评论者信息的获取方式,例如从数据库、第三方 API 等获取。

理解 wp_get_current_commenter() 函数的工作原理,可以帮助我们更好地开发 WordPress 主题和插件,为用户提供更好的评论体验。

好了,今天的讲座就到这里。 希望大家有所收获! 咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注