大家好,我是今天的主讲人,江湖人称“代码老油条”。今天咱们来聊聊WordPress里一个挺重要的家伙——分类法(Taxonomy)。别害怕,听着高大上,其实就是给文章、帖子们分门别类的手段。
咱们这次要深入到它的骨髓里去,看看wp_terms
、wp_term_taxonomy
和wp_termmeta
这三个表是怎么勾搭在一起的。我保证,讲完之后,就算你不能立刻用代码变出个分类树,起码也能看懂别人写的代码,不至于一脸懵逼。
一、打个招呼:分类法是个什么鬼?
在WordPress的世界里,分类法就是一种组织内容的方式。最常见的例子就是文章的分类(Category)和标签(Tag)。你可以把文章扔进不同的分类,也可以给文章贴上不同的标签,这样用户就能更容易找到他们感兴趣的内容。
简单来说,分类法就像图书馆里的图书分类系统,让你能快速找到想看的书,而不是在一堆书里瞎翻。
二、三张表的爱恨情仇
这三个表,wp_terms
、wp_term_taxonomy
和wp_termmeta
,是分类法的核心。它们各司其职,又紧密联系,共同完成了分类的管理工作。
-
wp_terms
表:存储术语(Terms)这个表就像一个词汇表,记录了所有分类和标签的名字和别名。每个术语都有一个唯一的ID。
字段名 类型 说明 term_id
bigint(20) unsigned
术语ID,主键,自增 name
varchar(200)
术语名称,比如“新闻”、“技术”等 slug
varchar(200)
术语别名,用于URL,通常是英文,比如“news”、“tech”等 term_group
bigint(10)
术语组,用于区分不同的术语,通常为0 举个例子,假设你要创建一个名为“美食”的分类,那么
wp_terms
表里可能会出现这样一条记录:INSERT INTO `wp_terms` (`name`, `slug`, `term_group`) VALUES ('美食', 'food', 0);
-
wp_term_taxonomy
表:术语与分类法的关系这个表建立起了术语和分类法之间的联系。它记录了每个术语属于哪个分类法,以及这个术语在这个分类法下的描述、父级ID和文章计数。
字段名 类型 说明 term_taxonomy_id
bigint(20) unsigned
术语分类ID,主键,自增 term_id
bigint(20) unsigned
术语ID,外键,关联 wp_terms
表的term_id
taxonomy
varchar(32)
分类法名称,比如“category”、“post_tag”等 description
longtext
术语描述 parent
bigint(20) unsigned
父级ID,用于建立层级关系 count
bigint(20)
文章计数,表示有多少篇文章属于这个术语 继续上面的例子,假设“美食”分类的ID是5,那么
wp_term_taxonomy
表里可能会出现这样一条记录:INSERT INTO `wp_term_taxonomy` (`term_id`, `taxonomy`, `description`, `parent`, `count`) VALUES (5, 'category', '关于美食的文章', 0, 0);
-
wp_termmeta
表:术语的元数据这个表就像一个附加属性表,可以给每个术语添加自定义的元数据。比如,你可以给“美食”分类添加一个“封面图片”的元数据。
字段名 类型 说明 meta_id
bigint(20) unsigned
元数据ID,主键,自增 term_id
bigint(20) unsigned
术语ID,外键,关联 wp_terms
表的term_id
meta_key
varchar(255)
元数据键名,比如“封面图片”、“颜色”等 meta_value
longtext
元数据值 还是“美食”的例子,假设你要给它添加一个封面图片的元数据,那么
wp_termmeta
表里可能会出现这样一条记录:INSERT INTO `wp_termmeta` (`term_id`, `meta_key`, `meta_value`) VALUES (5, 'category_image', 'https://example.com/food.jpg');
三、代码实战:创建分类并获取信息
光说不练假把式,咱们来点实际的。
-
创建分类
WordPress提供了一系列函数来操作分类法。创建分类可以使用
wp_insert_term()
函数。$term = wp_insert_term( '旅游', // 术语名称 'category', // 分类法名称 array( 'description' => '关于旅游的文章', 'slug' => 'travel', 'parent' => 0 // 父级ID,0表示顶级分类 ) ); if ( is_wp_error( $term ) ) { echo '创建分类失败:' . $term->get_error_message(); } else { echo '创建分类成功,分类ID:' . $term['term_id']; }
这段代码会在
wp_terms
和wp_term_taxonomy
表中插入相应的记录。 -
获取分类信息
可以使用
get_term()
函数来获取分类信息。$term_id = 10; // 假设分类ID是10 $term = get_term( $term_id, 'category' ); if ( $term && ! is_wp_error( $term ) ) { echo '分类ID:' . $term->term_id . '<br>'; echo '分类名称:' . $term->name . '<br>'; echo '分类别名:' . $term->slug . '<br>'; echo '分类描述:' . $term->description . '<br>'; echo '文章计数:' . $term->count . '<br>'; } else { echo '获取分类信息失败'; }
这段代码会从
wp_terms
和wp_term_taxonomy
表中查询信息,并显示出来。 -
添加和获取元数据
可以使用
add_term_meta()
和get_term_meta()
函数来添加和获取元数据。$term_id = 10; // 假设分类ID是10 // 添加元数据 add_term_meta( $term_id, 'category_color', '#FF0000', true ); // 第四个参数true表示唯一键 // 获取元数据 $color = get_term_meta( $term_id, 'category_color', true ); if ( $color ) { echo '分类颜色:' . $color; } else { echo '没有找到分类颜色'; }
这段代码会在
wp_termmeta
表中插入一条记录,然后又把它读取出来。
四、源码分析:get_terms()
函数背后的故事
get_terms()
函数是获取分类列表的常用函数。咱们来扒一扒它的源码,看看它到底做了些什么。
(由于篇幅限制,这里只给出简化版的流程和关键代码片段,完整的源码请自行查阅。)
-
构建查询参数
get_terms()
函数接收一个参数数组,用于指定查询条件,比如分类法名称、排序方式、是否隐藏空分类等。 -
查询缓存
WordPress有强大的缓存机制。
get_terms()
函数首先会检查缓存中是否已经存在符合条件的分类列表。如果存在,直接返回缓存结果,避免重复查询数据库。 -
数据库查询
如果缓存中没有找到,
get_terms()
函数会构建SQL查询语句,从wp_terms
和wp_term_taxonomy
表中查询数据。// 关键代码片段 (简化版) $sql = "SELECT t.*, tt.* FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')"; if ( ! empty( $args['search'] ) ) { $sql .= " AND t.name LIKE '%" . esc_sql( $wpdb->esc_like( $args['search'] ) ) . "%'"; } $sql .= " ORDER BY " . esc_sql( $orderby ) . " " . esc_sql( $order );
-
处理查询结果
get_terms()
函数会将查询结果封装成WP_Term
对象数组,并根据参数进行排序、过滤等处理。 -
更新缓存
最后,
get_terms()
函数会将查询结果保存到缓存中,以便下次快速访问。
五、总结:三张表的联系
简单来说,这三张表的关系可以总结如下:
wp_terms
表存储所有术语的基本信息,比如名称和别名。wp_term_taxonomy
表建立术语和分类法之间的联系,并记录术语的描述、父级ID和文章计数。wp_termmeta
表存储术语的元数据,可以给每个术语添加自定义属性。
这三个表通过term_id
字段关联在一起,共同完成了分类法的管理工作。你可以把wp_terms
看作是“名词表”,wp_term_taxonomy
看作是“名词解释表”,wp_termmeta
看作是“名词补充说明表”。
六、进阶:自定义分类法
WordPress不仅提供了默认的分类法,比如分类和标签,还允许你创建自定义分类法。自定义分类法可以让你更灵活地组织内容,满足不同的需求。
创建自定义分类法可以使用register_taxonomy()
函数。
function register_book_taxonomy() {
$labels = array(
'name' => _x( '图书分类', 'taxonomy general name' ),
'singular_name' => _x( '图书分类', 'taxonomy singular name' ),
'search_items' => __( '搜索图书分类' ),
'all_items' => __( '所有图书分类' ),
'parent_item' => __( '父级图书分类' ),
'parent_item_colon' => __( '父级图书分类:' ),
'edit_item' => __( '编辑图书分类' ),
'update_item' => __( '更新图书分类' ),
'add_new_item' => __( '添加新图书分类' ),
'new_item_name' => __( '新图书分类名称' ),
'menu_name' => __( '图书分类' ),
);
$args = array(
'hierarchical' => true, // 是否具有层级关系
'labels' => $labels,
'show_ui' => true, // 是否显示在后台管理界面
'show_admin_column' => true, // 是否显示在文章列表的列
'query_var' => true, // 是否支持查询变量
'rewrite' => array( 'slug' => 'book_category' ), // URL别名
);
register_taxonomy( 'book_category', 'book', $args ); // 第一个参数是分类法名称,第二个参数是关联的文章类型
}
add_action( 'init', 'register_book_taxonomy', 0 );
这段代码会创建一个名为book_category
的自定义分类法,用于管理“图书”这种自定义文章类型。
七、总结的总结
好了,今天的讲座就到这里。希望通过今天的讲解,大家对WordPress的分类法有了更深入的了解。记住,wp_terms
、wp_term_taxonomy
和wp_termmeta
这三张表是分类法的核心,它们各司其职,又紧密联系,共同完成了分类的管理工作。
当然,分类法的内容远不止这些,还有很多细节和技巧需要大家在实践中不断摸索。记住,代码的世界是充满乐趣的,多写多练,你也能成为代码老油条!
如果大家还有什么问题,欢迎随时提问。下次有机会再和大家聊聊WordPress的其他技术细节。
祝大家编码愉快!