解析 WordPress `get_posts_by_author_id()` 函数源码:其内部如何调用 `WP_Query`。

各位观众,欢迎来到今天的“WordPress源码解密”特别节目。今天咱们的主题是:get_posts_by_author_id() 函数的内幕——它是怎么偷偷摸摸地召唤 WP_Query 大神的!准备好了吗?咱们这就开始扒它的底裤!

开场白:get_posts_by_author_id() 是个啥?

想象一下,你是个侦探,要找出某个作者发表的所有文章。get_posts_by_author_id() 函数就是你的放大镜,专门用来根据作者ID查找文章。它简化了操作,你不用亲自配置复杂的查询参数,就能轻松找到目标。

正戏:源码剖析——如何一步步调用 WP_Query

首先,我们来揭开 get_posts_by_author_id() 的真面目。这个函数其实并不复杂,它的主要任务就是准备好参数,然后交给 WP_Query 这个查询引擎来处理。

/**
 * Retrieve posts based on author ID.
 *
 * @since 2.1.0
 * @since 5.5.0 Added the `$args` parameter.
 *
 * @param int   $author_id Author ID.
 * @param array $args      {
 *     Optional. Array of arguments for get_posts(), which supports WP_Query().
 *
 *     @type int    $numberposts   Number of posts to retrieve. Default 5.
 *     @type int    $offset        Number of posts to offset in retrieving. Default 0.
 *     @type string $orderby       The field to order by. Accepts 'none', 'ID', 'author', 'title',
 *                                'date', 'modified', 'rand', 'comment_count', 'menu_order', 'meta_value',
 *                                'meta_value_num', 'post__in', 'post_name', 'post_parent', 'term_id',
 *                                'relevance', or any column registered via the {@see 'posts_orderby'} filter.
 *                                Default 'date'.
 *     @type string $order         Designates the ascending or descending order of the 'orderby' parameter.
 *                                Accepts 'ASC', 'DESC'. Default 'DESC'.
 *     @type string $post_type     Post type to retrieve. Accepts 'post', 'page', or any custom post type.
 *                                Default 'post'.
 *     @type string $post_status   Post status to retrieve. Accepts 'publish', 'pending', 'draft', 'auto-draft',
 *                                'future', 'private', 'inherit', 'trash', or any custom status.
 *                                Default 'publish'.
 * }
 * @return WP_Post[]|int[] Array of post objects or post IDs.
 */
function get_posts_by_author_id( $author_id, $args = null ) {
    $numberposts = 5;

    if ( is_array( $args ) ) {
        $args = wp_parse_args( $args, array(
            'numberposts' => 5,
        ) );

        if ( isset( $args['numberposts'] ) ) {
            $numberposts = absint( $args['numberposts'] );
        }
    } else {
        $args = array(
            'numberposts' => $numberposts,
        );
    }

    $args['author'] = $author_id;
    $posts = get_posts( $args );

    return $posts;
}

看到没?其实核心代码就那么几行。接下来,我们一步步拆解:

  1. 参数准备:

    • $author_id: 这是必须的,告诉函数你要找哪个作者的文章。
    • $args: 这是一个可选的数组,允许你自定义查询参数,比如你想找多少篇文章,按照什么排序等等。如果没有提供,函数会使用默认值。
  2. 默认参数与合并:

    • $numberposts = 5;: 默认情况下,函数只会返回 5 篇文章。
    • wp_parse_args(): 如果你提供了 $argswp_parse_args() 会将你的参数和默认参数合并。这意味着你可以只指定你想修改的参数,其他的参数会使用默认值。
    $args = wp_parse_args( $args, array(
        'numberposts' => 5,
    ) );

    这段代码的意思是,如果 $args 中没有 numberposts 这个键,就使用默认值 5。

  3. 关键一步:添加作者ID

    $args['author'] = $author_id;

    这一行代码至关重要,它把 $author_id 添加到 $args 数组中,作为 WP_Query 的查询条件。 WP_Query 识别 author 参数,并据此过滤文章。

  4. 重头戏:调用 get_posts()

    $posts = get_posts( $args );

    看到 get_posts() 了吗? 没错, get_posts_by_author_id() 函数其实是调用了 get_posts() 函数,而 get_posts() 函数才是真正调用 WP_Query 的幕后推手! get_posts() 接收 $args 作为参数,创建一个 WP_Query 对象,并执行查询。

  5. 返回结果:

    return $posts;

    get_posts() 函数会返回一个文章对象数组,或者一个文章 ID 数组,这取决于你在 $args 中设置的 fields 参数。 get_posts_by_author_id() 只是把这个结果原封不动地返回给你。

get_posts() 函数与 WP_Query 的关系

get_posts() 函数是一个便捷函数,它简化了 WP_Query 的使用。 你可以把它想象成一个 WP_Query 的包装器,它接收一些参数,然后帮你创建一个 WP_Query 对象,并执行查询。

function get_posts( $args = null ) {
    $defaults = array(
        'numberposts' => 5,
        'offset'      => 0,
        'category'    => 0,
        'orderby'     => 'date',
        'order'       => 'DESC',
        'include'     => array(),
        'exclude'     => array(),
        'meta_key'    => '',
        'meta_value'  => '',
        'post_type'   => 'post',
        'suppress_filters' => true,
    );

    $r = wp_parse_args( $args, $defaults );
    if ( empty( $r['post_status'] ) ) {
        $r['post_status'] = 'publish';
    }
    if ( ! empty( $r['numberposts'] ) && (int) $r['numberposts'] < 0 ) {
        $r['numberposts'] = 5;
    }

    $r = apply_filters( 'get_posts_args', $r );

    $get_posts = new WP_Query( $r );

    return $get_posts->posts;
}

可以看到,get_posts() 函数内部做了这些事情:

  1. 设置默认参数: 就像 get_posts_by_author_id() 一样,get_posts() 也有一堆默认参数,比如默认返回 5 篇文章,按照日期降序排列等等。

  2. 参数合并: wp_parse_args() 再次出场,合并你的参数和默认参数。

  3. WP_Query 对象创建: 关键的一步,$get_posts = new WP_Query( $r );,使用合并后的参数 $r 创建一个 WP_Query 对象。 这个对象会根据你提供的参数执行数据库查询。

  4. 返回结果: return $get_posts->posts;WP_Query 对象查询到的文章数据存储在 posts 属性中,get_posts() 函数把这个 posts 属性返回给你。

WP_Query 大神登场:它到底做了什么?

WP_Query 是 WordPress 中最核心的查询类,它负责根据你提供的参数,生成 SQL 查询语句,从数据库中检索数据,并将结果封装成文章对象。

简单来说,WP_Query 做了以下几件事情:

  1. 解析参数: 接收你提供的参数,比如 authorcategorypost_type 等等,把这些参数转换成 SQL 查询语句的条件。

  2. 构建 SQL 查询: 根据解析后的参数,构建复杂的 SQL 查询语句。 这个过程涉及到表连接、条件判断、排序等等,非常复杂。

  3. 执行查询: 将构建好的 SQL 查询语句发送到数据库执行。

  4. 处理结果: 从数据库中获取查询结果,并将每一行数据转换成一个 WP_Post 对象。

  5. 返回结果: 将所有 WP_Post 对象组成一个数组,返回给你。

一个更具体的例子:

假设我们调用 get_posts_by_author_id(123, array('numberposts' => 10, 'orderby' => 'title', 'order' => 'ASC'));,那么整个过程是这样的:

  1. get_posts_by_author_id() 接收到 $author_id = 123$args = array('numberposts' => 10, 'orderby' => 'title', 'order' => 'ASC')

  2. wp_parse_args()$args 与默认参数合并,得到 $args = array('numberposts' => 10, 'orderby' => 'title', 'order' => 'ASC', 'author' => 123)

  3. get_posts_by_author_id() 调用 get_posts($args)

  4. get_posts() 接收到 $args = array('numberposts' => 10, 'orderby' => 'title', 'order' => 'ASC', 'author' => 123)

  5. wp_parse_args() 再次将 $argsget_posts() 的默认参数合并(虽然这次合并几乎没有效果,因为 $args 已经包含了所有需要的参数)。

  6. get_posts() 创建 WP_Query 对象:$get_posts = new WP_Query(array('numberposts' => 10, 'orderby' => 'title', 'order' => 'ASC', 'author' => 123))

  7. WP_Query 对象解析参数,构建 SQL 查询语句。 这个 SQL 查询语句大概是这样的(简化版):

    SELECT *
    FROM wp_posts
    WHERE post_author = 123
    AND post_type = 'post'
    AND post_status = 'publish'
    ORDER BY post_title ASC
    LIMIT 10
  8. WP_Query 对象执行 SQL 查询,从数据库中获取数据。

  9. WP_Query 对象将查询结果转换成 WP_Post 对象数组。

  10. get_posts() 函数返回 WP_Post 对象数组。

  11. get_posts_by_author_id() 函数返回 WP_Post 对象数组。

总结:

get_posts_by_author_id() 函数是一个简单的便捷函数,它通过设置 author 参数并调用 get_posts() 函数,简化了根据作者 ID 查询文章的操作。 get_posts() 函数则是一个 WP_Query 的包装器,它负责创建 WP_Query 对象并执行查询。 而 WP_Query 才是真正干活的,它负责解析参数、构建 SQL 查询、执行查询、处理结果,最终返回文章数据。

表格总结:

函数 作用 内部如何调用 WP_Query
get_posts_by_author_id() 根据作者 ID 获取文章 1. 接收作者 ID 和可选的参数数组 $args。 2. 使用 wp_parse_args() 合并 $args 和默认参数。 3. 设置 $args['author'] = $author_id。 4. 调用 get_posts($args)。 5. 返回 get_posts() 的结果。
get_posts() 获取文章(更通用的函数) 1. 接收可选的参数数组 $args。 2. 使用 wp_parse_args() 合并 $args 和默认参数。 3. 创建 WP_Query 对象:$get_posts = new WP_Query( $r );。 4. 返回 $get_posts->posts,即 WP_Query 查询到的文章数组。
WP_Query WordPress 中最核心的查询类,负责根据参数生成 SQL 查询语句并执行查询 1. 接收参数数组。 2. 解析参数,构建 SQL 查询语句。 3. 执行 SQL 查询。 4. 将查询结果转换成 WP_Post 对象。 5. 将所有 WP_Post 对象组成一个数组,存储在 posts 属性中。 (这个类本身不被直接 "调用",而是通过 new WP_Query() 创建实例)

彩蛋:自定义查询的更多可能性

虽然 get_posts_by_author_id() 简化了操作,但它也限制了你的灵活性。 如果你需要更复杂的查询,比如根据多个作者 ID 查询,或者根据自定义字段查询,那么你可能需要直接使用 WP_Query

例如,要查询作者ID为123和456的文章,你可以这样做:

$args = array(
    'author' => '123,456', // 注意这里是逗号分隔的字符串
    'posts_per_page' => 10,
);

$query = new WP_Query( $args );

if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        // 在这里处理文章
        echo '<p>' . get_the_title() . '</p>';
    }
    wp_reset_postdata();
} else {
    echo '没有找到文章';
}

总结的总结:

get_posts_by_author_id() 就像一个自动挡汽车,方便易用,但不够灵活。 WP_Query 就像一个手动挡汽车,需要你亲自操作,但可以实现更复杂的驾驶技巧。 选择哪个取决于你的需求和技术水平。

好了,今天的“WordPress源码解密”节目就到这里。希望大家有所收获,下次再见!

发表回复

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