WordPress用户搜索实现姓名AND精确匹配方案
WordPress 用户搜索实现名与姓的AND逻辑匹配
默认情况下,WordPress用户搜索在输入「John Doe」这类全名时,会采用OR逻辑匹配——返回所有名字为John或姓氏为Doe的用户,无法精准筛选出同时符合名和姓的用户。以下是优化后的解决方案,实现名与姓的AND逻辑匹配:
add_action( 'pre_user_query', function( $uqi ) { global $wpdb; $search = ''; if ( isset( $uqi->query_vars['search'] ) ) $search = trim( $uqi->query_vars['search'] ); if ( $search ) { $search = trim($search, '*'); if (stristr($search, " ")) { $search_exp = explode(" ", $search); // 查询匹配名字的用户ID $query1 = $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'first_name' AND meta_value LIKE %s", '%' . $wpdb->esc_like($search_exp[0]) . '%' ); $vorname_ids = $wpdb->get_col($query1); // 查询匹配姓氏的用户ID $query2 = $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'last_name' AND meta_value LIKE %s", '%' . $wpdb->esc_like($search_exp[1]) . '%' ); $nachname_ids = $wpdb->get_col($query2); // 取两个结果的交集,即同时匹配名和姓的用户ID $fullname_ids = array_intersect($vorname_ids, $nachname_ids); if (!empty($fullname_ids)) { $placeholders = implode(',', array_fill(0, count($fullname_ids), '%d')); $search_meta = $wpdb->prepare("ID IN ($placeholders)", $fullname_ids); $uqi->query_where = str_replace( 'WHERE 1=1 AND (', "WHERE 1=1 AND ($search_meta OR ", $uqi->query_where ); } } else { $the_search = '%' . $wpdb->esc_like($search) . '%'; $search_meta = $wpdb->prepare(" ID IN ( SELECT user_id FROM {$wpdb->usermeta} WHERE ( ( meta_key='first_name' OR meta_key='last_name' OR meta_key='billing_city' ) AND {$wpdb->usermeta}.meta_value LIKE %s ) )", $the_search); $uqi->query_where = str_replace( 'WHERE 1=1 AND (', "WHERE 1=1 AND ($search_meta OR ", $uqi->query_where ); } } });
关键说明:
- 通过
pre_user_query钩子在用户查询执行前修改筛选条件 - 当搜索词包含空格时,拆分为名和姓两部分,分别查询匹配的用户ID列表
- 用
array_intersect获取同时符合名和姓的用户ID交集 - 修改查询WHERE子句,将交集用户ID作为核心筛选条件,同时保留原搜索逻辑的OR兼容(支持其他字段搜索)
- 修复了原代码中硬编码表前缀、SQL注入风险等问题,使用
wpdb->prepare和wpdb->esc_like确保代码安全性
内容的提问来源于stack exchange,提问作者Mister Woyng
相关产品推荐
相关产品推荐

