Answers:
我强烈建议丹尼尔(Daniel)比目前正确的解决方案简单得多的解决方案:
$user = get_userdata( $user_id );
if ( $user === false ) {
//user id does not exist
} else {
//user id exists
}
$user_ids = array_filter( $user_ids, 'get_userdata' );
在这种情况下,当它返回WP_User时,我将绝对不使用get_userdata($ user_id),因此它比自定义查询更贪婪。
关于查询,我同意使用prepare方法,但是SELECT COUNT(*)表示您将返回所有column,在这里没有用。
我建议不要使用SELECT COUNT(ID),这样,我们只处理更快的单个列。
另一方面,对于返回的语句,使用三元逻辑更容易阅读:
返回1 <$ count吗?真假;
总结起来,我会像这样实现它:
function user_id_exists( $user_id ) {
global $wpdb;
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->users WHERE ID = %d", $user_id ) );
return empty( $count ) || 1 > $count ? false : true;
}
SELECT COUNT(*)
,SELECT COUNT(ID)
两者都返回一列...计数。
如果要考虑性能,请使用:
function user_id_exists($user_id) {
global $wpdb;
// Check cache:
if (wp_cache_get($user_id, 'users')) return true;
// Check database:
if ($wpdb->get_var($wpdb->prepare("SELECT EXISTS (SELECT 1 FROM $wpdb->users WHERE ID = %d)", $user_id))) return true;
return false;
}
否则,请使用get_userdata($user_id) !== false
。调用get_userdata
将从数据库中检索整行而不是单个值,创建一个新的WP_User对象,并在成功时将其缓存。
尝试这不会向您显示警告,例如wpdb :: prepare()缺少参数2
function user_id_exists($user_id){
global $wpdb;
$count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->users WHERE ID = %d",$user_id));
if($count == 1){ return true; }else{ return false; }
}
return $count == 1;
至少有一些黑客(我知道是因为我至少是这个游戏的受害者)做过的事情是使用这种类型的URL访问您的网站
domain.com/?author=0
domain.com/?author=1
等等
如果尝试成功,站点的输出将具有有效的数据,此外,用户nicename将出现在网站的内容中,昵称也可能存在于此(取决于输出的页面)。
如果尝试无效,则站点将转到404页面(或在未找到页面的错误上进行任何设置)。
使用cURL构建可以在相对较短的时间内测试从author = 0到author = 999的脚本并输出用户名列表的脚本可能很简单。我有一个黑客为我的一个站点执行此操作,然后尝试使用另一组常用密码登录到每个用户。
您可以想象,第一次发生这种情况时,看到有人可以很容易地找到您的所有用户名,这有点令人恐惧。对我来说很幸运,那天保存了强大的密码,我敢肯定并不是每个人都那么幸运。
我已经在几个著名的网站(在这篇文章中它们将保持匿名)上测试了这一点,看来到目前为止,任何人都无法做任何事情来阻止这种情况的发生。我个人认为,WordPress应当关闭是安全隐患。
编辑:
在将来(2016年初),我现在知道有些方法/插件可以阻止此用户枚举攻击。而且我进一步改变了对这种安全风险的立场,并且我不再认为WordPress应该改变这一点。
$user = get_userdata( $user_id ); if ( $user == false ){ //user id does not exist } else { //user id exists