/** * 可能认识的人 (可能认识的人 = 有相同tag的用户 || 所在城市相同的用户 || 好友的好友 || 我的粉丝 || 随机推荐) * * 注意: 因为头像信息未保存数据库, 所以当开启"隐藏无头像的用户"时, 结果集数量可能小于$max * * @param int $uid 用户ID * @param int $max 获取的最大人数 * @param boolean $do_shuffle 是否随机次序 (默认:true) * @return boolean|array 用户ID的数组 */ public function getRelatedUser($uid, $max = 100, $do_shuffle = true) { if (($uid = intval($uid)) <= 0) { return false; } // 权重设置 $config = model('Xdata')->lget('related_user'); $tag_weight = isset($config['tag_weight']) ? intval($config['tag_weight']) : 4; // 拥有相同Tag $city_weight = isset($config['city_weight']) ? intval($config['city_weight']) : 3; // 设置的城市相同 $friend_weight = isset($config['friend_weight']) ? intval($config['friend_weight']) : 2; // 好友的好友 $follower_weight = isset($config['follower_weight']) ? intval($config['follower_weight']) : 1; // 我的粉丝 $total_weight = $tag_weight + $city_weight + $friend_weight + $follower_weight; // 是否隐藏无头像的用户 $hide_no_avatar = $config['hide_no_avatar']; // 权重对应的数量 $tag_count = intval($tag_weight / $total_weight * $max); $city_count = intval($city_weight / $total_weight * $max); $friend_count = intval($friend_weight / $total_weight * $max); $follower_count = intval($follower_weight / $total_weight * $max); $related_uids = array(); // 按Tag if ($tag_count > 0) { $tag_uids = $this->_getRelatedUserFromTag($uid, $related_uids, $tag_count); $related_uids = array_merge($related_uids, $tag_uids); } // 按设置的城市 if ($city_count > 0) { $limit = $city_count + ($tag_count - count($related_uids)); $city_uids = $this->_getRelatedUserFromCity($uid, $related_uids, $limit); $related_uids = array_merge($related_uids, $city_uids); } // 按好友的好友 if ($friend_count > 0) { $limit = $friend_count + ($tag_count + $city_count - count($related_uids)); $friend_uids = $this->_getRelatedUserFromFriend($uid, $related_uids, $limit); $related_uids = array_merge($related_uids, $friend_uids); } // 按粉丝 if ($follower_count > 0) { $limit = $follower_count + ($tag_count + $city_count + $friend_count - count($related_uids)); $follower_uids = $this->_getRelatedUserFromFollower($uid, $related_uids, $limit); $related_uids = array_merge($related_uids, $follower_uids); } // 随机推荐 $limit = $max - count($related_uids); $random_uids = $this->_getRandomRelatedUser($uid, $related_uids, $limit); $related_uids = array_merge($related_uids, $random_uids); // 按"好友的好友"推荐时, 可能会产生重复用户 $related_uids = array_unique($related_uids); // 添加推荐原因 foreach ($related_uids as $k => $v) { if ($hide_no_avatar && !hasUserFace($v)) { unset($related_uids[$k]); continue; } if (in_array($v, $tag_uids)) { $related_uids[$k] = array('uid' => $v, 'reason' => 'Tag相同'); } else { if (in_array($v, $city_uids)) { $related_uids[$k] = array('uid' => $v, 'reason' => '城市相同'); } else { if (in_array($v, $friend_uids)) { $related_uids[$k] = array('uid' => $v, 'reason' => '好友的好友'); } else { if (in_array($v, $follower_uids)) { $related_uids[$k] = array('uid' => $v, 'reason' => '您的粉丝'); } else { if (in_array($v, $random_uids)) { $related_uids[$k] = array('uid' => $v, 'reason' => '随机推荐'); } } } } } } if ($do_shuffle) { shuffle($related_uids); } return $related_uids; }
/** * 获取粉丝数最多的前N个用户 * * <p>当指定uid时, 该uid已关注的用户将被剔除. 注意: 数据量大时本操作较耗资源, 且结果集不会被缓存.</p> * <p>不指定uid时, 返回全站的粉丝排行榜, 该排行榜会缓存1小时.</p> * <p>当$hide_no_avatar为true时, 为了保证结果集数量, 实际查询的数量是3倍的$count, 然后再顺次剔除无头像的用户, * 所以最终结果集的数量可能会小于$count.</p> * * @param boolean $uid 用户ID * @param int $count 结果数 (默认:10) * @param null|boolean $hide_auto_friend 是否剔除默认关注的用户 (null时使用系统默认配置) * @param null|boolean $hide_no_avatar 是否剔除无头像的用户 (null时使用系统默认配置) * @return array */ public function getTopFollowerUser($uid = 0, $count = 10, $hide_auto_friend = null, $hide_no_avatar = null) { // 未指定参数时, 加载系统配置 $config = model('Xdata')->lget('top_follower'); !isset($hide_auto_friend) && ($hide_auto_friend = intval($config['hide_auto_friend'])); !isset($hide_no_avatar) && ($hide_no_avatar = intval($config['hide_no_avatar'])); $uid = intval($uid); $count = intval($count); $limit = 0; // 查询的结果数 $following = array(); // 已关注的用户 $top_user = array(); // 最终结果 if ($uid > 0) { $following = $this->query($this->getNowFollowingSql($uid)); $following = getSubByKey($following, 'fid'); $following = array_merge($following, array($uid)); // 自己不出现在最终结果中 $limit += count($following); } $cache_id = '_weibo_top_followed_' . $count . '_' . intval($hide_auto_friend) . intval($hide_no_avatar); $cache_tid = '_weibo_top_followed_t_' . $count . '_' . intval($hide_auto_friend) . intval($hide_no_avatar); if ($uid == 0) { // 缓存有效时间: 1 Hour $expire = 1 * 3600; if (($cache = S($cache_id)) === false) { S($cache_tid, time()); //缓存未设置 先设置缓存设定时间 } else { if (($cacheSetTime = S($cache_tid)) === false || $cacheSetTime + $expire <= time()) { S($cache_tid, time()); //缓存未设置 先设置缓存设定时间 } else { return $cache; } } } if ($uid > 0 || ($top_user = S($cache_id)) === false) { // 隐藏无头像用户时, 为了保证最后结果满足$limit, 查询时使用3倍的$limit $limit += $hide_no_avatar ? $count * 3 : $count; $where = 'WHERE `type` = 0 '; if ($hide_auto_friend) { // 隐藏默认关注的用户时 $auto_friend = model('Xdata')->get('register:register_auto_friend'); $auto_friend = explode(',', $auto_friend); if (count($auto_friend) > 1) { $where .= 'AND `fid` NOT IN ( ' . implode(',', $auto_friend) . ' )'; } } $sql = "SELECT `fid` AS `uid`, count(`uid`) AS `count` FROM {$this->tablePrefix}weibo_follow " . $where . " GROUP BY `fid` " . "ORDER BY `count` DESC LIMIT {$limit}"; $res = $this->query($sql); $res = $res ? $res : array(); if (!empty($res)) { // 过滤 $index = 1; $noPic = array(); foreach ($res as $k => $v) { if ($index > $count) { break; } else { if ($hide_no_avatar && !hasUserFace($v['uid'])) { // 剔除无头像的用户 $noPic[] = $v; unset($res[$k]); continue; } else { if ($uid > 0 && in_array($v['uid'], $following)) { // 剔除已关注的用户 unset($res[$k]); continue; } } } $top_user[] = $v; ++$index; } } unset($res); if (empty($top_user) && !empty($noPic)) { $top_user = $noPic; } if ($uid <= 0) { S($cache_id, empty($top_user) ? array() : $top_user); } } return $top_user; }