如何使用PHP函数get_posts来构建文章列表
WordPress的get_posts
是一个强大的函数,允许开发人员从WordPress数据库中检索内容。您可以最详细地指定要查找的文章、页面和自定义文章类型,获取自定义结果集,然后知识兔像PHP/MySQL忍者一样过滤和排序项目。
但是,如果知识兔您不是PHP专业人士,请不要害怕,有无数的PHP教程可供您观看或阅读并学习该语言。您只需要一点PHP知识即可创建自定义文章列表以显示在您的网站上,因为get_posts
函数保留了一组参数,允许构建简单或高级查询。
使用WordPress的get_posts
分为两个步骤:
- 首先,您必须构建自定义查询。实际上,它看起来不像MySQL查询,而且知识兔您不会编写任何
SELECT
语句。您只需要定义一个参数数组并将其传递给get_posts
函数。WordPress将该数组转换为真实且安全的MySQL查询,针对数据库运行它,并返回一个文章数组。 - 其次,您必须使用foreach循环遍历
get_posts
返回的结果集。
话虽如此,在这篇文章中,我们将首先深入探讨上面提到的关键概念,特别是如何get_posts
工作、如何构建自定义查询以及如何在前端站点上显示数据。然后知识兔,我将分享一个真实示例,其中包含一段代码,您可以在暂存环境中获取、编辑和使用代码片段,以进行测试和开发。
注意:我们通常区分文章、页面和自定义文章类型。在本文中,我们使用术语“post”来表示常规博客文章以及页面和自定义文章类型。所有这些文章类型都存储在数据库的“wp_posts”表中。文章类型之间的主要区别在于“post_type”字段的值。从开发人员的角度来看,文章、页面和自定义文章类型都是文章。
get_posts 函数简介
Codex对get_posts
函数的描述如下:
检索最新文章的数组,或与给定条件匹配的文章。
我们可以这样使用get_posts
:
$args = array('numberposts'=> 20,'category'=> 4);$my_posts = get_posts( $args );if( ! empty( $my_posts ) ){$output = '
- ';foreach ( $my_posts as $p ){$output .= '
- ' . $p->post_title . ' ';}$output .= '
上面的函数检索指定类别中的最新20篇博文(默认为'post_type'
is 'post'
)并返回一个对象数组$post
。您可以遍历数组以在屏幕上显示文章。这很容易,对吧?
get_posts
用于WP_Query
检索文章项目,并且知识兔它保留了一个包含相同参数的数组WP_Query
(除了少数例外)。所以我们有一个庞大的变量列表,知识兔可以用来构建我们的自定义查询。这些参数分为以下15个类别:
- Author参数
- Category参数
- Tag参数
- Taxonomy参数
- Search参数
- Post & Page参数
- Password参数
- Post Type参数
- Order & Orderby参数
- Date参数
- Custom Field (post meta) 参数
- Permission参数
- Mime Type参数
- Caching参数
- Return Fields参数
快速查看上面的列表可以让您了解可以针对WordPress数据库构建和运行的各种自定义查询。因此,知识兔让我们更深入地研究查询参数并开始构建我们的文章列表。
如何使用get_posts构建查询
每一类参数都与同一条信息相关。例如,我们可以构建一个查询来检索指定作者或排除指定作者的文章,通过ID或nicename定义作者。同样,我们可以构建查询,按类别、标签、分类、日期、自定义字段等获取文章。
如何使用参数构建简单查询
许多参数可以以非常相似的方式使用,无论它们属于哪个类别。例如,以下参数允许按文章作者查询数据库:
author
( int ) – 作者IDauthor_name
(字符串)——作者的user_nicename
author__in
( array ) – 多个作者ID的数组author__not_in
( array ) — 要从结果集中排除的多个作者ID的数组
我们如何使用这些参数?
在以下示例中,参数'author'
指定我们想要ID = 1的作者最近撰写的博客文章:
$my_posts = get_posts( array( 'author' => 1 ) );
相同的 ‘author’参数允许以不同的方式查询数据库:
// return an array of posts from specific authors$my_posts = get_posts( array( 'author' => '1,5,12' ) );
// return an array of posts excluding the specified author$my_posts = get_posts( array( 'author' => -1 ) );
因此,知识兔根据参数的值,您将获得一个结果集,其中包含来自单个作者(整数)、来自多个作者(逗号分隔值列表)或不包括作者(负值)的文章。
其他参数分享了额外的灵活性。例如,以下调用get_posts
返回多个作者的最新博客文章数组:
// return an array of posts from multiple authors$my_posts = get_posts( array( 'author__in' => array( 1, 5, 12 ) ) );
我们还可以排除多个作者:
// return an array of posts from multiple authors$my_posts = get_posts( array( 'author__not_in' => array( 1, 5, 12 ) ) );
同样,我们可以使用类别参数、标签参数、文章类型参数,但有一些具体的区别。例如,请参见类别参数:
cat
(整数)category_name
(字符串)category__and
(数组)category__in
(数组)category__not_in
(数组)
无论如何,并非所有参数都像这些参数一样易于使用。此外,我们可以在单个查询中使用类别参数、文章类型参数、mime类型参数等。这意味着我们可以对结果集中的项目进行精细控制,并且知识兔可以完全基于文章类型、自定义分类法和自定义字段构建更高级的查询。
所以,知识兔让我们更深入地研究吧!
如何在WordPress中构建高级查询
让我们通过基于自定义文章类型和自定义分类的更高级查询向前迈出一步。假设您有以下文章类型:
名称:书籍
分类名称:book_category、book_author
支持:标题、编辑器、缩略图、摘录、自定义字段
自定义文章类型和自定义分类法
假设您想要指定自定义分类book_category
中最新书籍的列表。这是参数数组:
$args = array('post_type'=> 'book','tax_query'=> array(array('taxonomy'=> 'book_category','field'=> 'slug','terms'=> 'sci-fi')),);
上面的参数只是告诉WordPress检索'sci-fi'
'book_category'
.
参数采用'tax_query'
参数数组的数组(即数组数组)。这些嵌套数组允许基于多种分类构建非常复杂的查询,如下例所示:
$args = array('numberposts'=> 10,'post_type'=> 'book','relation'=> 'AND','tax_query'=> array(array('taxonomy'=> 'book_category','field'=> 'slug','terms'=> 'sci-fi'),array('taxonomy'=> 'book_author','field'=> 'term_id','terms'=> 22)));
这些参数允许我们检索由ID #22编写的最新10个'book'
文章类型的列表。该参数设置 中列出的每个分类之间的逻辑关系。上面我们将其值设置为,因为我们需要检索属于作者 #22 所写类别的所有书籍。AND
这些参数允许我们检索由ID为#22的'book_author'
编写的'sci-fi'
'book_category'
中最新10种“book”文章类型的列表。'relation'
参数设置'tax_query'
中列出的每个分类法之间的逻辑关系。在上面,我们将其值设置为AND
,因为我们需要检索属于 'sci-fi'
类别AND
由作者#22撰写的所有书籍。
如何使用自定义字段参数构建元查询
有时,您可能需要根据特定的自定义字段键和/或值构建文章列表。
$args = array('meta_key'=> 'cover','meta_value'=> 'paperback','meta_compare'=> '=');
这些参数允许我们通过自定义字段键和值检索所有文章。'meta_compare'
设置测试'meta_value'
参数值所需的运算符。这里的'meta_value'
是'='
,这也是默认值。
可用值为'='
, '!='
, '>'
, '>='
, '<'
, '<='
, 'LIKE'
, 'NOT LIKE'
, 'IN'
, 'NOT IN'
, 'BETWEEN'
, 'NOT BETWEEN'
, 'NOT EXISTS'
, 'REGEXP'
,'NOT REGEXP'
或'RLIKE'
.
这是一个非常简单的示例,但我们可以构建更高级的查询。在下一个示例中,我们在数据库中查询2010年之后出版的奇幻书籍:
$args = array('post_type'=> 'book','meta_key'=> 'year_published','meta_value_num'=> 2010,'meta_compare'=> '>','tax_query'=> array(array('taxonomy'=> 'book_category','field'=> 'slug''terms'=> 'fantasy')));
我们可以走得更远。在下一个示例中,我们将一个文章类型与一个自定义分类法和两个自定义字段混合在一起:
$args = array('post_type'=> 'book','tax_query'=> array(array('taxonomy'=> 'book_category','field'=> 'slug''terms'=> array( 'fantasy' ))),'meta_query'=> array('relation'=> 'AND',array('key'=> 'year_published','value'=> 2010,'type'=> 'numeric','compare'=> '>',),array('key'=> 'price','value'=> array( 10, 25 ),'type'=> 'numeric','compare'=> 'BETWEEN',)));
在这里,我们设置了一组参数来检索2010年之后出版的幻想书籍列表,这些书籍的价格分别BETWEEN
为10和25。
您可以看到'meta_query'
参数的工作方式与参数非常相似'tax_query'
。它保留了一个数组数组,允许我们基于多个元键/值对构建高级查询。有关查询参数的完整列表和大量示例,请参阅WP_Query
文档。
为什么get_posts仅限于5个WordPress文章?
get_posts
函数采用与WP_Query::parse_query()
(参见Codex)相同的参数,但某些特定参数使其与WP_Query
对象的工作方式略有不同。
也许您没有在查询中使用'numberposts'
参数,并且知识兔想知道为什么您的列表中只看到5个项目。
默认情况下,您在设置 → 阅读管理页面中设置的文章数量决定了WordPress查询要检索的文章数量。无论如何,如果知识兔您没有为'numberposts'
或者'posts_per_page'
指定自定义值,则get_posts
返回不同数量的文章。
'numberposts'
是要检索的文章总数。它是'posts_per_page'
inWP_Query
的别名,但两者之间有区别:默认情况下,使用get_posts
时要检索的文章数为 5,而'posts_per_page'
inWP_Query
默认为WordPress博客每页的文章数。您可以通过为参数数组'numberposts'
或'posts_per_page'
在参数数组中设置自定义值来覆盖默认值。
除了'numberposts'
之外,以下参数是特定于get_posts
的:
'category'
是一个以逗号分隔的类别ID列表。它是WP_Query
中'cat'
参数的别名。'include'
是一个逗号分隔的文章ID列表。这是WP_Query
中'post__in'
参数的别名。'exclude'
是一个逗号分隔的文章ID列表。'suppress_filters'
指定是否抑制过滤器。此参数默认为true
inget_posts
,而默认为false
inWP_Query
(参见Track)。
get_posts
函数在wp-includes/post.php
中定义。get_posts
您可以通过查看Track (WordPress 5.2)或本地WordPress安装中的源代码来深入了解其工作原理。
项目排序
'orderby'
或'order'
并结果集中的项目进行排序。您可以按'ID'
, 'author'
, 'title'
, 'name'
, 'type'
, 'date'
, 'modified'
, 'parent'
,'rand'
和'comment_count'
许多其他方式按升序或降序对文章进行排序。
如果知识兔您有一个简单的查询,您只需要为'order'
和'orderby'
设置一个值。在以下示例中,文章按文章名称升序排序:
$args = array('author'=> '1,5,12','orderby'=> 'name','order'=> 'ASC');
这很简单。但是如果知识兔你有一个高级查询呢?即:我们可以在高级元查询中按一个或多个自定义字段值对项目进行排序吗?
WordPress 4.0和WordPress 4.2带来了重要的改进–'orderby'
和'meta_query'
参数。我们现在有了一种新的语法,知识兔用于按元查询的特定子句进行排序。由于新的语法,我们可以使用索引从'orderby'
参数创建对元查询的特定子句的引用。
由于这些改进,上例中的元查询可以写成如下:
$args = array('meta_query'=> array('relation'=> 'AND','year_clause' => array('key'=> 'year_published','value'=> 2010,'type'=> 'numeric','compare'=> '>',),'price_clause' => array('key'=> 'price','value'=> array( 10, 25 ),'type'=> 'numeric','compare'=> 'BETWEEN',)),'orderby' => 'price_clause',);
在上面的示例中,我们对'price_clause'
元素进行了排序。
我们可以做得更多。从WordPress 4.0开始,我们可以传递给get_posts
元查询索引数组而不是单个索引,如下例所示:
$args = array('meta_query'=> array('relation'=> 'AND','year_clause' => array('key'=> 'year_published','value'=> 2010,'type'=> 'numeric','compare'=> '>',),'price_clause' => array('key'=> 'price','value'=> array( 10, 25 ),'type'=> 'numeric','compare'=> 'BETWEEN',)),'orderby' => array( 'price_clause' => 'ASC', 'year_clause' => 'DESC' ),);
恭喜,您已经构建了一个高级元查询,并首先按'price_clause'
升序对结果进行排序,然后知识兔按'year_clause'
降序排序。
请参阅Codex中排序选项的完整列表。
是时候在首页上显示数据了。
推荐阅读:如何轻松创建和使用phpinfo页面。
如何显示get_posts返回的数据
WordPress的get_posts
返回一个WP_Post
对象数组,知识兔让我们可以访问存储在wp_posts
数据库表中的每个选定文章的许多变量:
- ID
- post_author
- post_name
- post_type
- post_title
- post_date
- post_date_gmt
- post_content
- post_excerpt
- post_status
- comment_status
- ping_status
- post_password
- post_parent
- post_modified
- post_modified_gmt
- comment_count
- menu_order
phpMyAdmin中的wp_posts表结构
您可以使用foreach
循环轻松访问这些数据,如下:
$custom_posts = get_posts( $args );if( ! empty( $custom_posts ) ){$output = '
- ';foreach ( $custom_posts as $p ){$output .= '
- ' . $p->post_title . ' ';}$output .= '
如果知识兔get_posts
找到至少一个文章,它会返回一个我们可以遍历的项目数组,以显示文章标题和指向原始文章的链接。我们使用get_permalink
函数来检索文章永久链接,因为我们没有相应的WP_Post
变量。
这很简单,但是我们如何实现该代码并使用WordPress构建我们的自定义文章列表get_posts
?
您可以通过多种方式在页面上显示文章列表。
- 您可以通过编辑子主题的页面模板将它们包含在页面的任何位置。
- 您可以将它们包含在侧边栏小工具中。
- 您可以使用自定义短代码将它们包含在文章的内容中
真实示例:如何使用简码显示自定义项目列表
我将向您展示如何构建可以包含在内容中的快速简便的短代码。无论如何,我不会深入研究短代码,因为我们已经在之前的博客文章中介绍了该主题。
首先,在本地WordPress安装wp-content/plugins
文件夹或临时环境中创建一个新目录。在此示例中,我将目录命名为wbolt-shortcodes。
在创建一个与新目录同名的 .php 文件:.wp-content/plugins/
wbolt-shortcodes/
wbolt-shortcodes.php
在您喜欢的文本编辑器中打开新文件并包含以下标题:
现在我们有了一个全新的插件,但它仍然什么也没做。浏览到WordPress仪表盘中的插件管理屏幕并激活新插件,确保您已在
wp-config.php
文件中将WP_DEBUG
设置为true
。您的沙盒现在已准备好进行黑客攻击。下一步是为自定义简码注册一个钩子:
/*** Add a hook for a shortcode tag*/function wbolt_shortcodes_init(){add_shortcode( 'wbolt_get_posts', 'wbolt_get_posts_cb' );}add_action('init', 'wbolt_shortcodes_init');
wbolt_get_posts
是短代码名称,wbolt_get_posts_cb
是下面定义的回调:/*** Register a shortcode** @param array $atts Array of shortcode attributes*/function wbolt_get_posts_cb( $atts ){// safely extract custom arguments and set default valuesextract( shortcode_atts(array('numberposts'=> 3,'post_type'=> 'post','book_category'=> 'fantasy','year_published'=> 1900,'price_min'=> 0,'price_max'=> 50),$atts,'wbolt_get_posts') );// define the array of query arguments$args = array('numberposts'=> $numberposts,'post_type'=> $post_type,'tax_query'=> array(array('taxonomy'=> 'book_category','field'=> 'slug','terms'=> $book_category,)),'meta_query'=> array('relation'=> 'AND','year_clause'=> array('key'=> 'year_published','value'=> $year_published,'type'=> 'numeric','compare'=> '>',),'price_clause'=> array('key'=> 'price','value'=> array( $price_min, $price_max ),'type'=> 'numeric','compare'=> 'BETWEEN',)),'orderby' => array( 'price_clause' => 'ASC' ));$custom_posts = get_posts( $args );if( ! empty( $custom_posts ) ){$output = '
- ';foreach ( $custom_posts as $p ){$output .= '
- ' . $p->post_title . ' (' . get_post_meta( $p->ID, 'year_published', true ) . ') - Price: ' . get_post_meta( $p->ID, 'price', true ) . ' ';}$output .= '
我们设置了六个用于定义参数数组的简码属性,最终将其传递给WordPressget_posts
函数。如果知识兔$custom_posts
不为空,则foreach
循环生成项目无序列表的HTML。
现在您和您博客的作者可以使用如下短代码包含文章列表:
[wbolt_get_posts post_type="book" book_category="sci-fi" numberposts="4" price_min=1 price_max=250]
当然,您可以根据需要更改参数数组,并在开发网站的任何文章或页面中运行测试。
使用get_posts函数构建的高级文章列表
下载仅供下载体验和测试学习,不得商用和正当使用。