如何使用 WP_User_Query 处理序列化数据
how to handle serialized data with WP_User_Query
我正在尝试在 Wordpress 中扩展自定义用户搜索;即,我想按城市、州和国家搜索用户,但这些数据是序列化的。
我的例子
meta_key: pie_address_3
;
meta_value: a:6:{s:7:"address";s:18:"New York Street, 4";s:8:"address2";s:0:"";s:4:"city";s:5:"Venice";s:5:"state";s:7:"Vicenza";s:3:"zip";s:5:"36015";s:7:"country";s:5:"Italy";}
这是我正在尝试做的事情:
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_query' => array(
'key' => 'pie_address_3',
'value' => $search,
'compare' => 'LIKE'
)
));
但是,当我输入某个国家或城市(我知道它与某个用户相关联)时,搜索结果 return 什么也没有。我该如何处理?谢谢!
更新
我已经像这样更新了 WP_User_Query
:
$args = array(
'meta_key' => 'pie_address_3'
);
$query = new WP_User_Query($args);
$authors = $query->get_results();
foreach ($authors as $author){
$c = get_user_meta($author->id,'pie_address_3',true);
if(isset($c)){
if(empty(get_user_meta($author->id,'address',true))){
add_user_meta($author->ID,'address',$c['address']);
}
if(empty(get_user_meta($author->id,'address2',true))){
add_user_meta($author->ID,'address2',$c['address2']);
}
if(empty(get_user_meta($author->id,'city',true))){
add_user_meta($author->ID,'city',$c['city']);
}
if(empty(get_user_meta($author->id,'state',true))){
add_user_meta($author->ID,'state',$c['state']);
}
if(empty(get_user_meta($author->id,'zip',true))){
add_user_meta($author->ID,'zip',$c['zip']);
}
if(empty(get_user_meta($author->id,'country',true))){
add_user_meta($author->ID,'country',$c['country']);
};
//delete_user_meta($author->ID,'pie_address_3',$c);
}
}
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'address',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'address2',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'city',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'state',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'zip',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'country',
'value' => $search,
'compare' => 'LIKE'
)
)
)
);
但是,它仍然不起作用。我哪里做错了?
更新答案
我意识到您需要在 pie_address_3
字段 OR 的至少一列中找到包含字符串 $search
的用户。
不幸的是,WP_User_Query
似乎不允许列和元字段之间存在 OR 关系。事实上,结果查询的 "conditional" 部分是这样的:
WHERE (
user_login LIKE '%$search%' OR
user_nicename LIKE '%$search%' OR
user_email LIKE '%$search%' OR
user_url LIKE '%$search%'
) AND (
wp_usermeta.meta_key = 'pie_address_3' AND
CAST(wp_usermeta.meta_value AS CHAR) LIKE '%$search%'
)
注意两部分之间的AND。
钩子 pre_user_query
在解析 WP_User_Query
之后触发,在执行查询之前,它通过引用传递当前 WP_User_Query
实例。因此,我们可以通过将此代码包含到我们的 functions.php
文件中来拦截 AND 并将其更改为 OR:
add_action('pre_user_query', 'my_custom_users_search');
function my_custom_users_search( $args ) {
$args->query_where = str_replace(') AND (', ') OR (', $args->query_where);
}
这将使以下查询有效:
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
警告:之前的动作函数会影响每个 WP_User_Query
调用!
为了防止我们可以将一个伪参数传递给WP_User_Query
函数,并在OR[=61=中更改AND ] 仅当该参数通过时。所以这是带有 and2or
虚拟参数的查询:
$my_users = new WP_User_Query(
array(
'and2or' => 1,
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
这是动作函数:
add_action('pre_user_query', 'my_custom_users_search');
function my_custom_users_search( $args ) {
if( isset( $args->query_vars['and2or'] ) )
$args->query_where = str_replace(') AND (', ') OR (', $args->query_where);
}
旧答案
这是搜索序列化元字段的查询(不需要拆分它,就像您在更新时所做的那样):
$my_users = new WP_User_Query(
array(
'role' => $role,
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
在您的查询中,您甚至在 search_columns
参数中指定的字段上搜索 $search
。
试试这个
$user_query = new WP_User_Query( array( 'meta_key' => 'pie_address_3', 'meta_value' => $keyword, 'meta_compare' => 'LIKE' ) );
compare (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS', and 'NOT EXISTS'. Default value is '='.
我正在尝试在 Wordpress 中扩展自定义用户搜索;即,我想按城市、州和国家搜索用户,但这些数据是序列化的。
我的例子
meta_key: pie_address_3
;
meta_value: a:6:{s:7:"address";s:18:"New York Street, 4";s:8:"address2";s:0:"";s:4:"city";s:5:"Venice";s:5:"state";s:7:"Vicenza";s:3:"zip";s:5:"36015";s:7:"country";s:5:"Italy";}
这是我正在尝试做的事情:
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_query' => array(
'key' => 'pie_address_3',
'value' => $search,
'compare' => 'LIKE'
)
));
但是,当我输入某个国家或城市(我知道它与某个用户相关联)时,搜索结果 return 什么也没有。我该如何处理?谢谢!
更新
我已经像这样更新了 WP_User_Query
:
$args = array(
'meta_key' => 'pie_address_3'
);
$query = new WP_User_Query($args);
$authors = $query->get_results();
foreach ($authors as $author){
$c = get_user_meta($author->id,'pie_address_3',true);
if(isset($c)){
if(empty(get_user_meta($author->id,'address',true))){
add_user_meta($author->ID,'address',$c['address']);
}
if(empty(get_user_meta($author->id,'address2',true))){
add_user_meta($author->ID,'address2',$c['address2']);
}
if(empty(get_user_meta($author->id,'city',true))){
add_user_meta($author->ID,'city',$c['city']);
}
if(empty(get_user_meta($author->id,'state',true))){
add_user_meta($author->ID,'state',$c['state']);
}
if(empty(get_user_meta($author->id,'zip',true))){
add_user_meta($author->ID,'zip',$c['zip']);
}
if(empty(get_user_meta($author->id,'country',true))){
add_user_meta($author->ID,'country',$c['country']);
};
//delete_user_meta($author->ID,'pie_address_3',$c);
}
}
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'address',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'address2',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'city',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'state',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'zip',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'country',
'value' => $search,
'compare' => 'LIKE'
)
)
)
);
但是,它仍然不起作用。我哪里做错了?
更新答案
我意识到您需要在 pie_address_3
字段 OR 的至少一列中找到包含字符串 $search
的用户。
不幸的是,WP_User_Query
似乎不允许列和元字段之间存在 OR 关系。事实上,结果查询的 "conditional" 部分是这样的:
WHERE (
user_login LIKE '%$search%' OR
user_nicename LIKE '%$search%' OR
user_email LIKE '%$search%' OR
user_url LIKE '%$search%'
) AND (
wp_usermeta.meta_key = 'pie_address_3' AND
CAST(wp_usermeta.meta_value AS CHAR) LIKE '%$search%'
)
注意两部分之间的AND。
钩子 pre_user_query
在解析 WP_User_Query
之后触发,在执行查询之前,它通过引用传递当前 WP_User_Query
实例。因此,我们可以通过将此代码包含到我们的 functions.php
文件中来拦截 AND 并将其更改为 OR:
add_action('pre_user_query', 'my_custom_users_search');
function my_custom_users_search( $args ) {
$args->query_where = str_replace(') AND (', ') OR (', $args->query_where);
}
这将使以下查询有效:
$my_users = new WP_User_Query(
array(
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
警告:之前的动作函数会影响每个 WP_User_Query
调用!
为了防止我们可以将一个伪参数传递给WP_User_Query
函数,并在OR[=61=中更改AND ] 仅当该参数通过时。所以这是带有 and2or
虚拟参数的查询:
$my_users = new WP_User_Query(
array(
'and2or' => 1,
'role' => $role,
'search' => '*' . $search . '*',
'search_columns' => array(
'user_login',
'user_nicename',
'user_email',
'user_url',
'display_name'
),
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
这是动作函数:
add_action('pre_user_query', 'my_custom_users_search');
function my_custom_users_search( $args ) {
if( isset( $args->query_vars['and2or'] ) )
$args->query_where = str_replace(') AND (', ') OR (', $args->query_where);
}
旧答案
这是搜索序列化元字段的查询(不需要拆分它,就像您在更新时所做的那样):
$my_users = new WP_User_Query(
array(
'role' => $role,
'meta_key' => 'pie_address_3',
'meta_value' => $search,
'meta_compare' => 'LIKE'
)
);
在您的查询中,您甚至在 search_columns
参数中指定的字段上搜索 $search
。
试试这个
$user_query = new WP_User_Query( array( 'meta_key' => 'pie_address_3', 'meta_value' => $keyword, 'meta_compare' => 'LIKE' ) );
compare (string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS', and 'NOT EXISTS'. Default value is '='.