WordPress默认的搜索功能搜索的是文章的标题和内容,在做网站开发的时候,我们可能需要根据内容的某个属性去搜索相应的记录,这时候用WordPress默认的搜索功能肯定是会有问题的,我们就需要通过自定义查询的方法来实现这个功能了,来看一下具体步骤。

通过修改搜索表单实现自定义字段搜索

建立自定义查询表单

这一步是最简单的,不涉及PHP,直接用HTML写一个表单即可。

添加自定义查询参数

因为WordPress的公共查询参数里面没有自定义字段,我们需要添加一个自定义查询参数,这样我们就可以通过这个自定义查询参数来传递需要查询的数据了。

add_filter( 'query_vars', 'add_query_vars_filter' );
function add_query_vars_filter( $vars ) {
	$vars[] = "phone";
	return $vars;
}

需要注意的是,自定义查询参数不能是WordPress内置查询参数中的任何一个,否则会引起冲突。

获取自定义查询参数

获取自定义查询参数的方法和获取内置查询参数的方法是一样的,都是通过`get_query_var`函数。

$phone = get_query_var('phone') ? get_query_var('phone) : '';

构建查询参数,新建查询

获取了自定义查询参数,我们就可以通过WordPress的meta参数查询相应的文章了。

$args = array(
    'meta_key' => 'phone'
	'meta_value' => $phone,
);
$wp_query = new WP_Query($args);

输出自定义查询结果

这一步就是循环输出查询到的数据的过程,和普通的文章输出没有实质的区别。

while ($wp_query->have_posts()) : $wp_query->the_post();
	get_template_part('content', 'stars');
endwhile;

通过修改搜索查询参数实现自定义字段搜索

除了上面比较基础的自定义表单方法,我们还可以通过修改WordPress默认的搜索查询参数来实现自定义字段搜索。要做到这点,我们需要使用三个WordPress Filter来实现。

1、过滤 JOIN 子句

首先,我们通过posts_join Filter 来修改 JOIN 子句。

function wprs_search_posts_join( $join, $query ) {
	if ( $query->is_search() ) {
		global $wpdb;
		$join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
	}
	return $join;
}
add_filter( 'posts_join', 'wprs_search_posts_join', 10, 2 );

默认情况下,WordPress 仅搜索“posts”表,由于自定义字段存储在“postsmeta”表中,我们需要将其包含在查询中,这就是上一个代码片段的作用。

2、过滤 WHERE 子句

下面我们将通过posts_where Filter 来过滤 WHERE 子句 posts_where。

function wprs_search_posts_where( $where, $query ) {
    if ( $query->is_search() ) {
		global $wpdb;
		$where = preg_replace(
			"/(s*{$wpdb->posts}.post_titles+LIKEs*('[^']+')s*)/",
			"({$wpdb->posts}.post_title LIKE $1) OR ({$wpdb->postmeta}.meta_value LIKE $1)",
			$where
		);
    }
    return $where;
}
add_filter( 'posts_where', 'wprs_search_posts_where', 10, 2 );

上面的代码告诉 WordPress 执行搜索查询同时查询 meta_value 数据列,这将搜索所有自定义字段的值。如果你希望 WordPress 只搜索特定字段的值,代码将更加复杂。

3、过滤 DISTINC 子句(可选)

最后我们可以过滤 posts_distinct Hook,如果我们在不同的字段中为同一篇文章添加了具有相同值的自定义字段,这段代码可防止出现重复的搜索结果。

function wprs_search_posts_distinct( $where, $query ) {
	if ( $query->is_search() ) {
		return "DISTINCT";
	}
	return $where;
}
add_filter( 'posts_distinct', 'wprs_search_posts_distinct', 10, 2 );

把上面三段代码放到主题的 functions.php 文件或者插件中的适合文件中,我们就可以让WordPress默认搜索表单搜索自定义字段的值了。