<?php
// ================== 配置区域 ==================
define('BING_CACHE_FILE', 'bing_cache.json'); // 壁纸信息缓存文件
define('BING_CACHE_TIME', 12 * 3600); // 缓存时间12小时
define('DB_FILE', 'bing_wallpaper.db'); // SQLite数据库文件
// =============================================
// ================== 初始化SQLite ==================
$need_db_init = !file_exists(DB_FILE);
try {
$db = new PDO('sqlite:' . DB_FILE);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 创建壁纸表 (预留备用字段1-3)
$db->exec("
CREATE TABLE IF NOT EXISTS wallpapers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
hash TEXT UNIQUE, -- 图片唯一标识
title TEXT,
copyright TEXT,
copyrightlink TEXT,
url TEXT, -- UHD图片地址
url_1080p TEXT, -- 1080P图片地址
date TEXT, -- 日期 enddate
year INTEGER, -- 年份(用于分类)
month INTEGER, -- 月份(用于分类)
reserve1 TEXT, -- 备用字段1
reserve2 TEXT, -- 备用字段2
reserve3 TEXT, -- 备用字段3
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
");
// 创建索引
$db->exec("CREATE INDEX IF NOT EXISTS idx_year_month ON wallpapers (year, month)");
$db->exec("CREATE INDEX IF NOT EXISTS idx_date ON wallpapers (date)");
} catch (PDOException $e) {
die("数据库初始化失败: " . $e->getMessage());
}
// ==================================================
// 获取当前脚本完整URL(用于生成链接)
$self = $_SERVER['PHP_SELF'];
$base_url = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['SCRIPT_NAME']), '/') . '/';
// ================== 获取必应壁纸函数 ==================
function getBingWallpaper($db, $cache_file, $cache_time) {
// 检查缓存是否存在且未过期
$use_cache = false;
$bing_data = null;
$result = null;
if (file_exists($cache_file)) {
$cache_mtime = filemtime($cache_file);
$current_time = time();
// 如果缓存文件在12小时内,则使用缓存
if (($current_time - $cache_mtime) < $cache_time) {
$cached_content = file_get_contents($cache_file);
$cached_data = json_decode($cached_content, true);
// 验证缓存数据是否有效
if (isset($cached_data['success']) && $cached_data['success']) {
$result = $cached_data;
$use_cache = true;
}
}
}
// 如果缓存无效或过期,则从必应获取新数据
if (!$use_cache) {
// 获取bing每日壁纸
$bing_url = 'https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN';
// 使用curl获取bing数据
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $bing_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
$bing_raw_data = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($bing_raw_data && !$curl_error) {
$bing_json = json_decode($bing_raw_data, true);
if (isset($bing_json['images'][0])) {
$image = $bing_json['images'][0];
$base_url = 'https://www.bing.com';
// 获取高清版图片(替换为UHD版本)
$image_url = $base_url . $image['url'];
$uhd_url = str_replace('1920x1080', 'UHD', $image_url);
// 解析年月
$enddate = $image['enddate'] ?? '';
$year = $month = 0;
if (strlen($enddate) >= 6) {
$year = intval(substr($enddate, 0, 4));
$month = intval(substr($enddate, 4, 2));
} else {
$year = intval(date('Y'));
$month = intval(date('m'));
}
// 构建返回数据
$result = array(
'success' => true,
'title' => $image['title'] ?? '必应每日壁纸',
'copyright' => $image['copyright'] ?? '',
'copyrightlink' => isset($image['copyrightlink']) ? $base_url . $image['copyrightlink'] : '',
'url' => $uhd_url,
'url_1080p' => $base_url . $image['url'],
'date' => $enddate,
'hash' => $image['hsh'] ?? '',
'cache_time' => date('Y-m-d H:i:s', time()),
'cache_expire' => date('Y-m-d H:i:s', time() + $cache_time)
);
// 保存到缓存文件
file_put_contents($cache_file, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX);
// 存入SQLite数据库(如果不存在)
try {
$stmt = $db->prepare("SELECT id FROM wallpapers WHERE hash = ?");
$stmt->execute([$result['hash']]);
if (!$stmt->fetch()) {
$insert = $db->prepare("
INSERT INTO wallpapers (hash, title, copyright, copyrightlink, url, url_1080p, date, year, month, reserve1, reserve2, reserve3)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, '', '', '')
");
$insert->execute([
$result['hash'],
$result['title'],
$result['copyright'],
$result['copyrightlink'],
$result['url'],
$result['url_1080p'],
$result['date'],
$year,
$month
]);
}
} catch (PDOException $e) {
error_log("SQLite insert error: " . $e->getMessage());
}
} else {
$result = array(
'success' => false,
'error' => '获取必应壁纸失败:数据格式错误'
);
}
} else {
$result = array(
'success' => false,
'error' => '获取必应壁纸失败:' . ($curl_error ?: '未知错误')
);
}
}
return $result;
}
// ================== 路由处理 ==================
$action = isset($_GET['action']) ? $_GET['action'] : '';
// 1. 壁纸列表页面 (带年月分类)
if ($action === 'list') {
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$per_page = 20;
$offset = ($page - 1) * $per_page;
// 获取年月筛选
$selected_year = isset($_GET['year']) ? intval($_GET['year']) : 0;
$selected_month = isset($_GET['month']) ? intval($_GET['month']) : 0;
// 获取所有可用的年份月份
$year_month_list = [];
$stmt = $db->query("SELECT DISTINCT year, month FROM wallpapers WHERE year IS NOT NULL AND month IS NOT NULL ORDER BY year DESC, month DESC");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$year_month_list[] = $row;
}
// 构建查询条件
$where_sql = "1=1";
$params = [];
if ($selected_year > 0) {
$where_sql .= " AND year = :year";
$params[':year'] = $selected_year;
if ($selected_month > 0) {
$where_sql .= " AND month = :month";
$params[':month'] = $selected_month;
}
}
// 查询总数
$count_stmt = $db->prepare("SELECT COUNT(*) FROM wallpapers WHERE $where_sql");
foreach ($params as $key => $val) $count_stmt->bindValue($key, $val);
$count_stmt->execute();
$total = $count_stmt->fetchColumn();
$total_pages = ceil($total / $per_page);
// 查询当前页数据
$sql = "SELECT * FROM wallpapers WHERE $where_sql ORDER BY date DESC, id DESC LIMIT :limit OFFSET :offset";
$stmt = $db->prepare($sql);
foreach ($params as $key => $val) $stmt->bindValue($key, $val);
$stmt->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$wallpapers = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.5, user-scalable=yes">
<title>必应壁纸列表 - 按年月归档</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Segoe UI', Roboto, sans-serif; background: #f5f7fa; padding: 20px; }
.container { max-width: 1400px; margin: 0 auto; }
h1 { font-size: 1.8rem; margin-bottom: 20px; color: #2c3e50; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
h1 a { font-size: 1rem; background: #3498db; color: white; padding: 8px 16px; border-radius: 30px; text-decoration: none; }
.filter-form { background: white; padding: 15px 20px; border-radius: 40px; box-shadow: 0 4px 10px rgba(0,0,0,0.05); margin-bottom: 30px; display: flex; flex-wrap: wrap; gap: 15px; align-items: center; }
.filter-group { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
select { padding: 10px 18px; border-radius: 40px; border: 1px solid #ddd; background: white; font-size: 1rem; cursor: pointer; outline: none; }
.btn { background: #3498db; color: white; border: none; padding: 10px 24px; border-radius: 40px; font-size: 1rem; cursor: pointer; text-decoration: none; display: inline-block; transition: background 0.2s; }
.btn:hover { background: #2980b9; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 20px; }
.card { background: white; border-radius: 16px; overflow: hidden; box-shadow: 0 5px 15px rgba(0,0,0,0.08); transition: transform 0.2s; text-decoration: none; color: inherit; display: block; }
.card:hover { transform: translateY(-5px); box-shadow: 0 12px 20px rgba(0,0,0,0.15); }
.card-img { width: 100%; aspect-ratio: 16/9; object-fit: cover; display: block; background: #eee; }
.card-info { padding: 15px; }
.card-title { font-weight: 600; margin-bottom: 6px; color: #2c3e50; font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-copyright { font-size: 0.8rem; color: #7f8c8d; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-date { font-size: 0.75rem; color: #95a5a6; margin-top: 8px; }
.pagination { margin-top: 40px; display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }
.pagination a, .pagination span { display: inline-block; padding: 10px 16px; border-radius: 40px; background: white; text-decoration: none; color: #3498db; border: 1px solid #e0e0e0; }
.pagination .current { background: #3498db; color: white; border-color: #3498db; }
.empty-msg { text-align: center; padding: 60px 20px; color: #7f8c8d; font-size: 1.2rem; }
@media (max-width: 600px) {
body { padding: 15px; }
h1 { font-size: 1.5rem; }
.filter-form { border-radius: 24px; flex-direction: column; align-items: stretch; }
.btn { text-align: center; }
}
</style>
</head>
<body>
<div class="container">
<h1>
📅 必应壁纸归档
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3C%3Fphp+echo+htmlspecialchars%28%24self%29%3B+%3F%3E" class="btn">🏠 返回首页</a>
</h1>
<form method="get" class="filter-form">
<input type="hidden" name="action" value="list">
<div class="filter-group">
<select name="year" onchange="this.form.submit()">
<option value="0">全部年份</option>
<?php
$years = array_unique(array_column($year_month_list, 'year'));
rsort($years);
foreach ($years as $y): ?>
<option value="<?php echo $y; ?>" <?php echo $selected_year == $y ? 'selected' : ''; ?>><?php echo $y; ?>年</option>
<?php endforeach; ?>
</select>
<select name="month" onchange="this.form.submit()" <?php echo $selected_year == 0 ? 'disabled' : ''; ?>>
<option value="0">全部月份</option>
<?php for ($m = 1; $m <= 12; $m++): ?>
<option value="<?php echo $m; ?>" <?php echo $selected_month == $m ? 'selected' : ''; ?>><?php echo $m; ?>月</option>
<?php endfor; ?>
</select>
</div>
<noscript><button type="submit" class="btn">筛选</button></noscript>
</form>
<?php if (empty($wallpapers)): ?>
<div class="empty-msg">✨ 暂无壁纸记录,先去首页获取一张吧~</div>
<?php else: ?>
<div class="grid">
<?php foreach ($wallpapers as $item): ?>
<a href="<?php echo $self; ?>?action=view&id=<?php echo $item['id']; ?>" class="card">
<img class="card-img" src="<?php echo htmlspecialchars($item['url_1080p']); ?>" loading="lazy" alt="<?php echo htmlspecialchars($item['title']); ?>">
<div class="card-info">
<div class="card-title"><?php echo htmlspecialchars(mb_substr($item['title'], 0, 30)); ?></div>
<div class="card-copyright"><?php echo htmlspecialchars(mb_substr($item['copyright'], 0, 40)); ?></div>
<div class="card-date"><?php echo $item['year']; ?>年<?php echo $item['month']; ?>月</div>
</div>
</a>
<?php endforeach; ?>
</div>
<?php if ($total_pages > 1): ?>
<div class="pagination">
<?php if ($page > 1): ?>
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3Faction%3Dlist%26page%3D%3C%3Fphp+echo+%24page-1%3B+%3F%3E%26year%3D%3C%3Fphp+echo+%24selected_year%3B+%3F%3E%26month%3D%3C%3Fphp+echo+%24selected_month%3B+%3F%3E">上一页</a>
<?php endif; ?>
<?php
$start = max(1, $page - 2);
$end = min($total_pages, $page + 2);
for ($i = $start; $i <= $end; $i++):
?>
<?php if ($i == $page): ?>
<span class="current"><?php echo $i; ?></span>
<?php else: ?>
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3Faction%3Dlist%26page%3D%3C%3Fphp+echo+%24i%3B+%3F%3E%26year%3D%3C%3Fphp+echo+%24selected_year%3B+%3F%3E%26month%3D%3C%3Fphp+echo+%24selected_month%3B+%3F%3E"><?php echo $i; ?></a>
<?php endif; ?>
<?php endfor; ?>
<?php if ($page < $total_pages): ?>
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3Faction%3Dlist%26page%3D%3C%3Fphp+echo+%24page%2B1%3B+%3F%3E%26year%3D%3C%3Fphp+echo+%24selected_year%3B+%3F%3E%26month%3D%3C%3Fphp+echo+%24selected_month%3B+%3F%3E">下一页</a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</body>
</html>
<?php
exit;
}
// 2. 查看单张壁纸详情 (点击列表进入大图)
if ($action === 'view' && isset($_GET['id'])) {
$id = intval($_GET['id']);
$stmt = $db->prepare("SELECT * FROM wallpapers WHERE id = ?");
$stmt->execute([$id]);
$item = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$item) {
header('Location: ' . $self . '?action=list');
exit;
}
// 直接重定向到高清图片
header('Location: ' . $item['url']);
exit;
}
// 3. 必应API数据接口 (原bz逻辑)
if (isset($_GET['bz'])) {
$result = getBingWallpaper($db, BING_CACHE_FILE, BING_CACHE_TIME);
// 如果请求参数中有 json,返回JSON数据
if (isset($_GET['json'])) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
exit;
}
// 默认:重定向到图片
if ($result['success']) {
header('Location: ' . $result['url']);
} else {
header('Content-Type: application/json; charset=utf-8');
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
exit;
}
// ================== 首页:全屏展示当前壁纸 ==================
// 获取今日壁纸(优先缓存,没有则实时获取)
$wallpaper = getBingWallpaper($db, BING_CACHE_FILE, BING_CACHE_TIME);
// 如果获取失败,尝试从数据库获取最新的一张作为备用
if (!$wallpaper['success']) {
$stmt = $db->query("SELECT * FROM wallpapers ORDER BY date DESC, id DESC LIMIT 1");
$latest = $stmt->fetch(PDO::FETCH_ASSOC);
if ($latest) {
$wallpaper = [
'success' => true,
'title' => $latest['title'],
'copyright' => $latest['copyright'],
'url' => $latest['url'],
'id' => $latest['id']
];
}
}
// 查询上一张壁纸 (按id倒序,取比当前小的最大id)
$prev = null;
if (isset($wallpaper['id']) && $wallpaper['id'] > 0) {
$stmt = $db->prepare("SELECT * FROM wallpapers WHERE id < ? ORDER BY id DESC LIMIT 1");
$stmt->execute([$wallpaper['id']]);
$prev = $stmt->fetch(PDO::FETCH_ASSOC);
} else {
// 如果没有id(刚获取还没存入数据库?但getBingWallpaper已经存入,所以应该有id)
// 或者取最新的一张作为当前,然后取上一张
$stmt = $db->query("SELECT * FROM wallpapers ORDER BY id DESC LIMIT 1");
$current = $stmt->fetch(PDO::FETCH_ASSOC);
if ($current) {
$wallpaper['id'] = $current['id'];
$wallpaper['title'] = $current['title'];
$wallpaper['copyright'] = $current['copyright'];
$wallpaper['url'] = $current['url'];
// 再查上一张
$stmt2 = $db->prepare("SELECT * FROM wallpapers WHERE id < ? ORDER BY id DESC LIMIT 1");
$stmt2->execute([$current['id']]);
$prev = $stmt2->fetch(PDO::FETCH_ASSOC);
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>必应每日壁纸 · 全屏</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body, html { width: 100%; height: 100%; overflow: hidden; font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; }
.wallpaper-container {
position: relative;
width: 100vw;
height: 100vh;
background: #000;
}
.wallpaper-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.info-panel {
position: absolute;
bottom: 30px;
left: 30px;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(8px);
color: white;
padding: 18px 28px;
border-radius: 60px;
max-width: 60%;
border: 1px solid rgba(255,255,255,0.2);
box-shadow: 0 10px 25px rgba(0,0,0,0.3);
line-height: 1.5;
pointer-events: none;
}
.info-panel .title {
font-size: 1.4rem;
font-weight: 500;
margin-bottom: 6px;
text-shadow: 0 2px 5px black;
}
.info-panel .copyright {
font-size: 0.9rem;
opacity: 0.9;
text-shadow: 0 1px 3px black;
}
.nav-panel {
position: absolute;
bottom: 30px;
right: 30px;
display: flex;
gap: 15px;
pointer-events: auto;
}
.nav-btn {
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(8px);
border: 1px solid rgba(255,255,255,0.3);
color: white;
padding: 14px 28px;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 500;
text-decoration: none;
transition: background 0.2s, transform 0.2s;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
cursor: pointer;
}
.nav-btn:hover {
background: rgba(30, 30, 30, 0.8);
transform: scale(1.05);
}
@media (max-width: 700px) {
.info-panel {
left: 15px;
bottom: 20px;
padding: 12px 20px;
max-width: 70%;
}
.info-panel .title { font-size: 1.1rem; }
.info-panel .copyright { font-size: 0.75rem; }
.nav-panel {
bottom: 20px;
right: 15px;
gap: 10px;
}
.nav-btn {
padding: 10px 18px;
font-size: 0.9rem;
}
}
@media (max-width: 480px) {
.info-panel { max-width: 85%; }
.nav-panel { flex-direction: column; gap: 8px; }
}
.error-msg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
background: rgba(0,0,0,0.7);
padding: 20px 40px;
border-radius: 50px;
font-size: 1.2rem;
}
</style>
</head>
<body>
<div class="wallpaper-container">
<?php if ($wallpaper && $wallpaper['success']): ?>
<img class="wallpaper-img" src="<?php echo htmlspecialchars($wallpaper['url']); ?>" alt="必应壁纸">
<div class="info-panel">
<div class="title"><?php echo htmlspecialchars($wallpaper['title'] ?: '今日壁纸'); ?></div>
<div class="copyright"><?php echo htmlspecialchars($wallpaper['copyright'] ?: ''); ?></div>
</div>
<div class="nav-panel">
<?php if ($prev): ?>
<a href="<?php echo $self; ?>?action=view&id=<?php echo $prev['id']; ?>" class="nav-btn">⬅ 上一张</a>
<?php else: ?>
<span class="nav-btn" style="opacity:0.4; pointer-events:none;">⬅ 上一张</span>
<?php endif; ?>
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3C%3Fphp+echo+%24self%3B+%3F%3E%3Faction%3Dlist" class="nav-btn">📋 壁纸列表</a>
</div>
<?php else: ?>
<div class="error-msg">
无法获取壁纸,请稍后刷新重试<br>
<a href="?url=https%3A%2F%2Fweb.daaee.cn%2F%3C%3Fphp+echo+%24self%3B+%3F%3E%3Faction%3Dlist" style="color:white; margin-top:10px; display:inline-block;">查看历史壁纸</a>
</div>
<?php endif; ?>
</div>
</body>
</html>
<?php
exit;
?>