本文目录导读:

我来详细介绍PHP信息流排序算法的实现方案:
基础排序算法实现
简单时间排序
<?php
class FeedSorter {
// 按时间倒序排列
public function sortByTime(array $feeds): array {
usort($feeds, function($a, $b) {
return strtotime($b['created_at']) - strtotime($a['created_at']);
});
return $feeds;
}
}
?>
热度加权排序(Hacker News算法)
<?php
class HackerNewsRanker {
/**
* Hacker News 热度算法
* Score = (P-1) / (T+2)^G
* P = 点赞数,T = 发布时间(小时),G = 重力因子(通常1.8)
*/
public function calculateScore(int $points, int $hoursAgo, float $gravity = 1.8): float {
if ($points <= 0) return 0;
return ($points - 1) / pow(($hoursAgo + 2), $gravity);
}
public function sortByHackerNews(array $feeds): array {
$now = time();
foreach ($feeds as &$feed) {
$hoursAgo = ($now - strtotime($feed['created_at'])) / 3600;
$feed['score'] = $this->calculateScore(
$feed['likes'] ?? 0,
$hoursAgo
);
}
usort($feeds, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return $feeds;
}
}
?>
Reddit热门排序算法
<?php
class RedditRanker {
/**
* Reddit 热门排序
* Score = log10(max(ups, 1)) + sign(ups-downs) * seconds/45000
*/
public function hotScore(int $ups, int $downs, string $createdAt): float {
$seconds = max(1, strtotime($createdAt) - 1134028003);
$score = log10(max($ups, 1)) + ($ups - $downs) * $seconds / 45000;
return $score;
}
public function sortByHot(array $feeds): array {
foreach ($feeds as &$feed) {
$ups = $feed['likes'] ?? 0;
$downs = $feed['dislikes'] ?? 0;
$feed['score'] = $this->hotScore($ups, $downs, $feed['created_at']);
}
usort($feeds, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return $feeds;
}
}
?>
综合权重排序算法
<?php
class ComprehensiveRanker {
private $weights = [
'time' => 0.4,
'likes' => 0.3,
'comments' => 0.2,
'shares' => 0.1
];
// 配置权重
public function setWeights(array $weights): void {
$this->weights = array_merge($this->weights, $weights);
}
/**
* 计算综合得分
*/
public function calculateScore(array $feed): float {
// 时间衰减因子(48小时衰减)
$timeScore = $this->timeDecay($feed['created_at'], 48);
// 互动得分归一化
$likeScore = $this->normalize($feed['likes'] ?? 0);
$commentScore = $this->normalize($feed['comments'] ?? 0);
$shareScore = $this->normalize($feed['shares'] ?? 0);
return (
$this->weights['time'] * $timeScore +
$this->weights['likes'] * $likeScore +
$this->weights['comments'] * $commentScore +
$this->weights['shares'] * $shareScore
);
}
// 时间衰减函数(指数衰减)
private function timeDecay(string $timestamp, int $halfLifeHours): float {
$ageHours = (time() - strtotime($timestamp)) / 3600;
return pow(0.5, $ageHours / $halfLifeHours);
}
// 归一化(对数归一化)
private function normalize(int $value): float {
if ($value <= 0) return 0;
return log10($value + 1) / log10(10001); // 上限10000
}
public function sortFeeds(array $feeds): array {
foreach ($feeds as &$feed) {
$feed['score'] = $this->calculateScore($feed);
}
usort($feeds, function($a, $b) {
return $b['score'] <=> $a['score'];
});
return $feeds;
}
}
?>
基于用户偏好的个性化排序
<?php
class PersonalizedRanker {
private $userInterests = [];
private $userHistory = [];
public function __construct(array $userInterests, array $userHistory) {
$this->userInterests = $userInterests; // 兴趣标签权重
$this->userHistory = $userHistory; // 历史互动记录
}
/**
* 个性化推荐排序
*/
public function personalizedScore(array $feed): float {
$baseScore = 0;
$interestScore = 0;
$historyScore = 0;
// 1. 内容标签匹配度
if (isset($feed['tags'])) {
foreach ($feed['tags'] as $tag) {
if (isset($this->userInterests[$tag])) {
$interestScore += $this->userInterests[$tag];
}
}
}
// 2. 历史行为偏好
if (isset($this->userHistory[$feed['author_id']])) {
$historyScore = $this->userHistory[$feed['author_id']] * 0.1;
}
// 3. 内容质量分(结合其他算法)
$qualityScore = $this->calculateQualityScore($feed);
// 综合计算
$baseScore = $interestScore * 0.5 + $historyScore * 0.2 + $qualityScore * 0.3;
return $baseScore;
}
private function calculateQualityScore(array $feed): float {
// 结合时间衰减和互动量
$timeFactor = $this->timeDecay($feed['created_at']);
$interactionFactor = log10(($feed['likes'] ?? 0) + ($feed['comments'] ?? 0) + 1);
return $timeFactor * $interactionFactor;
}
private function timeDecay(string $timestamp): float {
$hours = (time() - strtotime($timestamp)) / 3600;
return 1 / (1 + $hours * 0.01);
}
}
?>
分页与性能优化
<?php
class FeedPaginator {
/**
* 游标分页(比传统页码分页更高效)
*/
public function getFeedsWithCursor(PDO $pdo, ?string $cursor, int $limit = 20): array {
$sql = "SELECT * FROM feeds ";
if ($cursor) {
// 游标包含时间戳和ID
[$cursorTime, $cursorId] = explode('_', $cursor);
$sql .= "WHERE (created_at < :time) OR (created_at = :time AND id < :id) ";
}
$sql .= "ORDER BY created_at DESC, id DESC LIMIT :limit";
$stmt = $pdo->prepare($sql);
if ($cursor) {
$stmt->bindValue(':time', $cursorTime);
$stmt->bindValue(':id', $cursorId);
}
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->execute();
$feeds = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 生成下一次的游标
$nextCursor = null;
if (count($feeds) == $limit) {
$last = end($feeds);
$nextCursor = $last['created_at'] . '_' . $last['id'];
}
return [
'feeds' => $feeds,
'next_cursor' => $nextCursor
];
}
}
?>
缓存策略
<?php
class FeedCacheManager {
private $redis;
public function __construct(Redis $redis) {
$this->redis = $redis;
}
/**
* 缓存热门feed列表
*/
public function cacheHotFeeds(array $feeds, int $ttl = 300): void {
$key = 'feed:hot:' . date('YmdH');
$this->redis->setex($key, $ttl, json_encode($feeds));
}
/**
* 增量更新排序(新feed插入时维护排序列表)
*/
public function addFeedToSortedSet(string $feedId, float $score): void {
$key = 'feed:scores:day:' . date('Ymd');
$this->redis->zadd($key, $score, $feedId);
// 保留前1000条
$this->redis->zremrangebyrank($key, 0, -1001);
}
/**
* 获取排序后的feed ID列表
*/
public function getTopFeeds(int $limit = 20): array {
$key = 'feed:scores:day:' . date('Ymd');
return $this->redis->zrevrange($key, 0, $limit - 1);
}
}
?>
完整示例
<?php
// 集成示例
class FeedService {
private $ranker;
private $cache;
public function __construct() {
// 配置权重
$this->ranker = new ComprehensiveRanker();
$this->ranker->setWeights([
'time' => 0.35,
'likes' => 0.25,
'comments' => 0.25,
'shares' => 0.15
]);
}
public function getFeedList(int $userId, int $page = 1, int $limit = 20): array {
// 获取原始feed
$feeds = $this->fetchFeedsFromDB($page, $limit);
// 个性化排序
$userInterests = $this->getUserInterests($userId);
$userHistory = $this->getUserHistory($userId);
$personalRanker = new PersonalizedRanker($userInterests, $userHistory);
foreach ($feeds as &$feed) {
// 综合排序 + 个性化加权
$feed['score'] = $this->ranker->calculateScore($feed) * 0.7 +
$personalRanker->personalizedScore($feed) * 0.3;
}
// 排序和分页
usort($feeds, function($a, $b) {
if ($b['score'] == $a['score']) {
return strtotime($b['created_at']) <=> strtotime($a['created_at']);
}
return $b['score'] <=> $a['score'];
});
return array_slice($feeds, ($page - 1) * $limit, $limit);
}
}
?>
算法选择建议
- 小型社区:简单时间排序足够型平台**:Reddit/Hacker News算法较合适
- 社交平台:需要个性化排序
- 商业场景:综合权重算法更佳
选择时要考虑业务目标、用户规模、内容特性和性能要求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播