In today's digital era, website development has become an indispensable part of many businesses and individuals. In this process, user avatars, as important elements for enhancing user experience, play a crucial role. They not only enhance users' personalized experience but also improve website interactivity and attractiveness. Among the many avatar services, Gravatar, as a widely used service, although providing convenient and quick service, its problems such as slow access speed and dependency on third-party services are becoming increasingly prominent. These issues not only affect user experience but also bring potential risks to website stability and security. Today I will share a brand new solution - deploying your own completely autonomous and controllable social avatar system. Through this approach, you can easily break free from dependence on external services and achieve complete control over the avatar system. This not only improves website access speed and stability but also protects user privacy and data security.
在当今的数字化时代,网站开发已经成为了许多企业和个人不可或缺的一部分。在这一过程中,用户头像作为提升用户体验的重要元素,扮演着至关重要的角色。它不仅能够增强用户的个性化体验,还能提升网站的互动性和吸引力。在众多的头像服务中,Gravatar作为广泛使用的服务,虽然提供了方便快捷的服务,但其访问速度慢、依赖第三方服务等问题也日益凸显。这些问题不仅影响了用户的使用体验,也给网站的稳定性和安全性带来了潜在的风险。今天我将分享一种全新的解决方案——自己部署一个完全自主可控的社交头像系统。通过这种方式,你可以轻松摆脱对外部服务的依赖,实现对头像系统的完全控制。这不仅可以提升网站的访问速度和稳定性,还能保护用户的隐私和数据安全。
Retain Gravatar
This plan is the one I am currently using, but I only used the random part because it can make my comment section avatar style consistent and also benefit the overall loading speed of the website.
Features / 特性 ✨
相比直接使用Gravatar,这个系统提供了更好的控制性和稳定性。当用户没有Gravatar头像时,系统会自动分配一个美观的默认头像,而不是显示难看的默认图标。同时,所有Gravatar头像都会被缓存到本地,大大提升了加载速度。
系统采用单文件架构,部署极其简单,只需上传一个PHP文件即可运行。内置的管理系统让头像管理变得直观便捷,无需手动编辑配置文件。
这个系统特别适合需要稳定头像服务的个人博客、企业网站或任何需要用户头像功能的Web应用。
API / 调用示例
默认头像API: https://www.penlife.cn/avatar/index.php?api=user@example.com
Gravatar兼容API: https://www.penlife.cn/avatar/index.php?api_gravatar=user@example.com&s=80
HTML使用示例: <img src="https://www.penlife.cn/avatar/index.php?api=user@example.com" alt="头像">
Code / 代码示例
// 配置
define('ADMIN_PASSWORD', '000000'); // 填写你的密码
define('JSON_FILE', 'pic_link.json'); // 随机头像存放地址(JSON)
define('GRAVATAR_CACHE_DIR', 'gravatar_download'); // Gravatar头像存放文件夹
// 创建必要的目录
if (!file_exists(GRAVATAR_CACHE_DIR)) {
mkdir(GRAVATAR_CACHE_DIR, 0755, true);
}
// 初始化JSON文件
if (!file_exists(JSON_FILE)) {
file_put_contents(JSON_FILE, json_encode([], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
class AvatarSystem {
public function __construct() {
session_start();
}
// 处理请求路由
public function handleRequest() {
if (isset($_GET['api'])) {
$this->handleApiRequest();
} elseif (isset($_GET['api_gravatar'])) {
$this->handleGravatarRequest();
} elseif (isset($_POST['action'])) {
$this->handleAdminAction();
} else {
$this->showAdminPanel();
}
}
// 处理API请求
private function handleApiRequest() {
$email = $_GET['api'];
$md5_hash = md5(strtolower(trim($email)));
$avatars = $this->loadAvatars();
if (empty($avatars)) {
$this->returnError('没有可用的默认头像');
return;
}
// 使用MD5哈希选择头像
$index = hexdec(substr($md5_hash, 0, 8)) % count($avatars);
$avatar_url = $avatars[$index];
// 重定向到选中的头像
header('Location: ' . $avatar_url);
exit;
}
// 处理Gravatar兼容请求
private function handleGravatarRequest() {
$email = $_GET['api_gravatar'];
$md5_hash = md5(strtolower(trim($email)));
$cache_file = GRAVATAR_CACHE_DIR . '/' . $md5_hash . '.jpg';
// 检查缓存
if (file_exists($cache_file)) {
$this->outputImage($cache_file);
return;
}
// 从Gravatar下载
$size = isset($_GET['s']) ? intval($_GET['s']) : 80;
$size = min(max($size, 1), 2048); // 限制尺寸范围
$gravatar_url = "https://www.gravatar.com/avatar/{$md5_hash}?s={$size}&d=404";
$image_data = @file_get_contents($gravatar_url);
if ($image_data !== false) {
// 保存到缓存
file_put_contents($cache_file, $image_data);
$this->outputImage($cache_file);
} else {
// Gravatar不存在,使用默认头像
$this->handleApiRequest();
}
}
// 输出图片
private function outputImage($file_path) {
$mime_type = mime_content_type($file_path);
header('Content-Type: ' . $mime_type);
header('Content-Length: ' . filesize($file_path));
header('Cache-Control: public, max-age=86400'); // 缓存1天
readfile($file_path);
exit;
}
// 处理管理员操作
private function handleAdminAction() {
if (!$this->isLoggedIn()) {
echo json_encode(['success' => false, 'message' => '未登录']);
return;
}
switch ($_POST['action']) {
case 'add_avatar':
$this->addAvatar($_POST['url']);
break;
case 'delete_avatar':
$this->deleteAvatar($_POST['index']);
break;
case 'clear_cache':
$this->clearCache();
break;
}
}
// 添加头像
private function addAvatar($url) {
if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
echo json_encode(['success' => false, 'message' => '无效的URL']);
return;
}
$avatars = $this->loadAvatars();
if (!in_array($url, $avatars)) {
$avatars[] = $url;
$this->saveAvatars($avatars);
echo json_encode(['success' => true, 'message' => '头像添加成功']);
} else {
echo json_encode(['success' => false, 'message' => '头像已存在']);
}
}
// 删除头像
private function deleteAvatar($index) {
$avatars = $this->loadAvatars();
if (isset($avatars[$index])) {
array_splice($avatars, $index, 1);
$this->saveAvatars($avatars);
echo json_encode(['success' => true, 'message' => '头像删除成功']);
} else {
echo json_encode(['success' => false, 'message' => '头像不存在']);
}
}
// 清理缓存
private function clearCache() {
$files = glob(GRAVATAR_CACHE_DIR . '/*');
$count = 0;
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
$count++;
}
}
echo json_encode(['success' => true, 'message' => "已清理 {$count} 个缓存文件"]);
}
// 加载头像列表
private function loadAvatars() {
$content = file_get_contents(JSON_FILE);
return json_decode($content, true) ?: [];
}
// 保存头像列表
private function saveAvatars($avatars) {
file_put_contents(JSON_FILE, json_encode($avatars, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
// 检查登录状态
private function isLoggedIn() {
return isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true;
}
// 登录处理
private function handleLogin() {
if (isset($_POST['password']) && $_POST['password'] === ADMIN_PASSWORD) {
$_SESSION['admin_logged_in'] = true;
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
return false;
}
// 退出登录
private function handleLogout() {
session_destroy();
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
// 显示管理面板
private function showAdminPanel() {
if (isset($_POST['password'])) {
$this->handleLogin();
}
if (isset($_GET['logout'])) {
$this->handleLogout();
}
if (!$this->isLoggedIn()) {
$this->showLoginForm();
return;
}
$avatars = $this->loadAvatars();
$base_url = $this->getBaseUrl();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>社交头像系统管理</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; background: #f5f5f5; padding: 20px; }
.container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.header { background: #2c3e50; color: white; padding: 20px; }
.header h1 { margin-bottom: 10px; }
.header .info { opacity: 0.8; font-size: 14px; }
.content { padding: 20px; }
.section { margin-bottom: 30px; }
.section h2 { margin-bottom: 15px; color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 5px; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; color: #34495e; }
input[type="text"], input[type="url"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; }
button { background: #3498db; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-size: 14px; }
button:hover { background: #2980b9; }
button.danger { background: #e74c3c; }
button.danger:hover { background: #c0392b; }
.avatar-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; }
.avatar-item { border: 1px solid #ddd; border-radius: 8px; padding: 15px; text-align: center; }
.avatar-item img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; margin-bottom: 10px; }
.avatar-item .url { font-size: 12px; color: #666; word-break: break-all; margin-bottom: 10px; }
.alert { padding: 10px; border-radius: 4px; margin-bottom: 15px; }
.alert.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.alert.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 20px; }
.stat-card { background: #ecf0f1; padding: 15px; border-radius: 8px; text-align: center; }
.stat-card .number { font-size: 24px; font-weight: bold; color: #2c3e50; }
.stat-card .label { font-size: 14px; color: #7f8c8d; margin-top: 5px; }
.usage-examples { background: #f8f9fa; padding: 15px; border-radius: 8px; }
.usage-examples h3 { margin-bottom: 10px; color: #2c3e50; }
.usage-examples code { background: #e9ecef; padding: 2px 6px; border-radius: 3px; font-family: monospace; }
.usage-examples p { margin-bottom: 8px; }
.logout { float: right; background: #e74c3c; }
.logout:hover { background: #c0392b; }
@media (max-width: 768px) {
.avatar-list { grid-template-columns: 1fr; }
.stats { grid-template-columns: 1fr; }
.header .logout { float: none; margin-top: 10px; }
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>小雨社交头像-PHP实例</h1>
<div class="info">此版本仅供学习参考使用 正式生产环境不保证SLA</div>
<a href="?logout=1" class="logout button">退出登录</a>
</div>
<div class="content">
<div class="section">
<h2>系统统计</h2>
<div class="stats">
<div class="stat-card">
<div class="number"><?php echo count($avatars); ?></div>
<div class="label">默认头像数量</div>
</div>
<div class="stat-card">
<div class="number"><?php echo count(glob(GRAVATAR_CACHE_DIR . '/*')); ?></div>
<div class="label">Gravatar缓存数量</div>
</div>
<div class="stat-card">
<div class="number"><?php echo file_exists(JSON_FILE) ? round(filesize(JSON_FILE)/1024, 2) : 0; ?>KB</div>
<div class="label">配置文件大小</div>
</div>
</div>
</div>
<div class="section">
<h2>使用说明</h2>
<div class="usage-examples">
<h3>API调用方式:</h3>
<p><strong>默认头像API:</strong> <code><?php echo $base_url; ?>?api=user@example.com</code></p>
<p><strong>Gravatar兼容API:</strong> <code><?php echo $base_url; ?>?api_gravatar=user@example.com&s=80</code></p>
<p><strong>HTML使用示例:</strong> <code><img src="<?php echo $base_url; ?>?api=user@example.com" alt="头像"></code></p>
</div>
</div>
<div class="section">
<h2>添加默认头像</h2>
<form id="addAvatarForm">
<div class="form-group">
<label for="avatar_url">头像URL:</label>
<input type="url" id="avatar_url" name="url" placeholder="https://example.com/avatar.jpg" required>
</div>
<button type="submit">添加头像</button>
</form>
</div>
<div class="section">
<h2>默认头像列表 (<?php echo count($avatars); ?>个)</h2>
<?php if (empty($avatars)): ?>
<p style="color: #666; text-align: center; padding: 40px;">暂无默认头像,请先添加一些头像</p>
<?php else: ?>
<div class="avatar-list">
<?php foreach ($avatars as $index => $url): ?>
<div class="avatar-item">
<img src="<?php echo htmlspecialchars($url); ?>" alt="头像" onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjRjBGMEYwIi8+CjxwYXRoIGQ9Ik00MCA0MEMzNS44IDQwIDMyIDM2LjIgMzIgMzJDMzIgMjcuOCAzNS44IDI0IDQwIDI0QzQ0LjIgMjQgNDggMjcuOCA0OCAzMkM0OCAzNi4yIDQ0LjIgNDAgNDAgNDBaTTQwIDQ0QzMxLjE2IDQ0IDI0IDUxLjE2IDI0IDYwVjY0SDU2VjYwQzU2IDUxLjE2IDQ4Ljg0IDQ0IDQwIDQ0WiIgZmlsbD0iI0NDQ0NDQyIvPgo8L3N2Zz4K'">
<div class="url"><?php echo htmlspecialchars($url); ?></div>
<button class="danger" onclick="deleteAvatar(<?php echo $index; ?>)">删除</button>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<div class="section">
<h2>缓存管理</h2>
<p style="margin-bottom: 15px; color: #666;">当前Gravatar缓存目录中有 <?php echo count(glob(GRAVATAR_CACHE_DIR . '/*')); ?> 个文件</p>
<button class="danger" onclick="clearCache()">清理Gravatar缓存</button>
</div>
</div>
</div>
<script>
// 添加头像
document.getElementById('addAvatarForm').addEventListener('submit', function(e) {
e.preventDefault();
const url = document.getElementById('avatar_url').value;
fetch('', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=add_avatar&url=' + encodeURIComponent(url)
})
.then(response => response.json())
.then(data => {
showAlert(data.message, data.success ? 'success' : 'error');
if (data.success) {
document.getElementById('avatar_url').value = '';
setTimeout(() => location.reload(), 1000);
}
});
});
// 删除头像
function deleteAvatar(index) {
if (confirm('确定要删除这个头像吗?')) {
fetch('', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=delete_avatar&index=' + index
})
.then(response => response.json())
.then(data => {
showAlert(data.message, data.success ? 'success' : 'error');
if (data.success) {
setTimeout(() => location.reload(), 1000);
}
});
}
}
// 清理缓存
function clearCache() {
if (confirm('确定要清理所有Gravatar缓存吗?')) {
fetch('', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=clear_cache'
})
.then(response => response.json())
.then(data => {
showAlert(data.message, data.success ? 'success' : 'error');
if (data.success) {
setTimeout(() => location.reload(), 1000);
}
});
}
}
// 显示提示信息
function showAlert(message, type) {
const alert = document.createElement('div');
alert.className = 'alert ' + type;
alert.textContent = message;
const content = document.querySelector('.content');
content.insertBefore(alert, content.firstChild);
setTimeout(() => alert.remove(), 3000);
}
</script>
</body>
</html>
<?php
}
// 显示登录表单
private function showLoginForm() {
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>社交头像系统 - 登录</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); height: 100vh; display: flex; align-items: center; justify-content: center; }
.login-container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); width: 100%; max-width: 400px; }
.login-container h1 { text-align: center; margin-bottom: 30px; color: #2c3e50; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 8px; color: #34495e; font-weight: bold; }
input[type="password"] { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; }
button { width: 100%; background: #3498db; color: white; border: none; padding: 12px; border-radius: 6px; font-size: 16px; cursor: pointer; }
button:hover { background: #2980b9; }
.error { color: #e74c3c; text-align: center; margin-top: 15px; }
.info { text-align: center; color: #7f8c8d; margin-top: 20px; font-size: 14px; }
</style>
</head>
<body>
<div class="login-container">
<h1>社交头像系统</h1>
<form method="POST">
<div class="form-group">
<label for="password">管理员密码:</label>
<input type="password" id="password" name="password" required autofocus>
</div>
<button type="submit">登录</button>
<?php if (isset($_POST['password'])): ?>
<div class="error">密码错误,请重试</div>
<?php endif; ?>
</form>
<div class="info">
替代Gravatar的头像服务系统<br>
请输入管理员密码进入管理界面
</div>
</div>
</body>
</html>
<?php
}
// 获取基础URL
private function getBaseUrl() {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$script = $_SERVER['SCRIPT_NAME'];
return $protocol . '://' . $host . $script;
}
// 返回错误信息
private function returnError($message) {
header('Content-Type: text/plain');
echo 'Error: ' . $message;
exit;
}
}
// 运行系统
$system = new AvatarSystem();
$system->handleRequest();
?>
Reserve Gravatar
Due to time constraints, this solution was generated using AI (Claube4 Sonnet) and was not used for testing in a production environment. Please pay attention to data security
Features / 特性 ✨
单文件PHP部署,无需数据库。集成邮箱验证、SMTP发送、图片自动转换处理。兼容Gravatar API调用格式,支持用户自定义头像上传与管理。内置管理后台可配置默认头像库,MD5随机分配机制确保个性化展示。提供完整的用户注册验证流程,图片自动优化为标准格式,部署简单维护便捷。
API / 调用示例
默认头像API: https://www.penlife.cn/avatar/index.php?api=user@example.com
Gravatar兼容API: https://www.penlife.cn/avatar/index.php?api_gravatar=user@example.com&s=80
HTML使用示例: <img src="https://www.penlife.cn/avatar/index.php?api=user@example.com" alt="头像">
Code / 代码
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 配置
define('ADMIN_PASSWORD', '000000');
define('UPLOAD_DIR', 'uploads/');
define('PIC_LINK_FILE', 'pic_link.json');
define('USER_EMAIL_CODE_FILE', 'user_email_code.json');
define('CONFIG_FILE', 'config.json');
// 创建必要的目录
if (!is_dir(UPLOAD_DIR)) {
mkdir(UPLOAD_DIR, 0755, true);
}
// 初始化文件
function initFiles() {
if (!file_exists(PIC_LINK_FILE)) {
file_put_contents(PIC_LINK_FILE, json_encode([], JSON_PRETTY_PRINT));
}
if (!file_exists(USER_EMAIL_CODE_FILE)) {
file_put_contents(USER_EMAIL_CODE_FILE, json_encode([], JSON_PRETTY_PRINT));
}
if (!file_exists(CONFIG_FILE)) {
$defaultConfig = [
'smtp_host' => '',
'smtp_port' => 587,
'smtp_username' => '',
'smtp_password' => '',
'from_email' => '',
'from_name' => '头像系统'
];
file_put_contents(CONFIG_FILE, json_encode($defaultConfig, JSON_PRETTY_PRINT));
}
}
initFiles();
// 工具函数
function generateCode() {
return str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
}
function sendEmail($to, $subject, $body) {
$config = json_decode(file_get_contents(CONFIG_FILE), true);
if (empty($config['smtp_host'])) {
return false;
}
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$headers .= "From: {$config['from_name']} <{$config['from_email']}>\r\n";
return mail($to, $subject, $body, $headers);
}
function getRandomAvatar() {
$picLinks = json_decode(file_get_contents(PIC_LINK_FILE), true);
if (empty($picLinks)) {
return null;
}
return $picLinks[array_rand($picLinks)];
}
function getUserAvatar($email) {
$userCodes = json_decode(file_get_contents(USER_EMAIL_CODE_FILE), true);
foreach ($userCodes as $user) {
if ($user['email'] === $email && isset($user['avatar'])) {
return $user['avatar'];
}
}
return null;
}
function convertImage($source, $destination, $size = 80) {
$imageInfo = getimagesize($source);
$sourceType = $imageInfo[2];
switch ($sourceType) {
case IMAGETYPE_JPEG:
$sourceImage = imagecreatefromjpeg($source);
break;
case IMAGETYPE_PNG:
$sourceImage = imagecreatefrompng($source);
break;
case IMAGETYPE_GIF:
$sourceImage = imagecreatefromgif($source);
break;
default:
return false;
}
$sourceWidth = imagesx($sourceImage);
$sourceHeight = imagesy($sourceImage);
$destImage = imagecreatetruecolor($size, $size);
imagecopyresampled($destImage, $sourceImage, 0, 0, 0, 0, $size, $size, $sourceWidth, $sourceHeight);
$success = imagepng($destImage, $destination);
imagedestroy($sourceImage);
imagedestroy($destImage);
return $success;
}
// 路由处理
$action = $_GET['action'] ?? $_GET['api'] ?? $_GET['email_code'] ?? $_GET['user_first'] ?? $_GET['user_dash'] ?? 'admin';
// API处理
if (isset($_GET['api'])) {
$email = $_GET['api'];
$size = $_GET['s'] ?? $_GET['size'] ?? 80;
// 检查用户是否有自定义头像
$userAvatar = getUserAvatar($email);
if ($userAvatar) {
header('Content-Type: image/png');
readfile($userAvatar);
exit;
}
// 使用MD5生成随机头像
$md5 = md5($email);
$randomAvatar = getRandomAvatar();
if ($randomAvatar) {
header('Content-Type: image/png');
readfile($randomAvatar);
} else {
// 生成默认头像
$img = imagecreate($size, $size);
$bg = imagecolorallocate($img, 200, 200, 200);
$text = imagecolorallocate($img, 100, 100, 100);
imagestring($img, 5, $size/2-10, $size/2-10, '?', $text);
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
}
exit;
}
// 邮箱验证码申领
if (isset($_GET['email_code'])) {
if ($_POST) {
$email = $_POST['email'];
$code = generateCode();
$userCodes = json_decode(file_get_contents(USER_EMAIL_CODE_FILE), true);
$userCodes[$email] = [
'email' => $email,
'code' => $code,
'timestamp' => time()
];
file_put_contents(USER_EMAIL_CODE_FILE, json_encode($userCodes, JSON_PRETTY_PRINT));
$subject = '头像系统验证码';
$body = "您的验证码是:<strong>{$code}</strong><br>有效期10分钟。";
if (sendEmail($email, $subject, $body)) {
echo "<script>alert('验证码已发送到您的邮箱!'); window.location.href='?user_first';</script>";
} else {
echo "<script>alert('发送失败,请检查SMTP配置!');</script>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>申领验证码</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; padding: 20px; }
input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; }
button { width: 100%; padding: 10px; background: #007cba; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:hover { background: #005a87; }
</style>
</head>
<body>
<h2>申领验证码</h2>
<form method="post">
<input type="email" name="email" placeholder="请输入邮箱地址" required>
<button type="submit">发送验证码</button>
</form>
</body>
</html>
<?php
exit;
}
// 用户首次验证
if (isset($_GET['user_first'])) {
if ($_POST) {
$email = $_POST['email'];
$code = $_POST['code'];
$website = $_POST['website'] ?? '';
$userCodes = json_decode(file_get_contents(USER_EMAIL_CODE_FILE), true);
if (isset($userCodes[$email]) && $userCodes[$email]['code'] === $code) {
if (time() - $userCodes[$email]['timestamp'] < 600) { // 10分钟有效期
$userCodes[$email]['verified'] = true;
$userCodes[$email]['website'] = $website;
file_put_contents(USER_EMAIL_CODE_FILE, json_encode($userCodes, JSON_PRETTY_PRINT));
echo "<script>alert('验证成功!'); window.location.href='?user_dash&email={$email}';</script>";
} else {
echo "<script>alert('验证码已过期!');</script>";
}
} else {
echo "<script>alert('验证码错误!');</script>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证邮箱</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; padding: 20px; }
input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; }
button { width: 100%; padding: 10px; background: #007cba; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:hover { background: #005a87; }
</style>
</head>
<body>
<h2>验证邮箱</h2>
<form method="post">
<input type="email" name="email" placeholder="邮箱地址" required>
<input type="text" name="code" placeholder="6位验证码" required>
<input type="url" name="website" placeholder="个人网站(选填)">
<button type="submit">验证</button>
</form>
</body>
</html>
<?php
exit;
}
// 用户dashboard
if (isset($_GET['user_dash'])) {
$email = $_GET['email'];
if ($_POST && isset($_FILES['avatar'])) {
$uploadFile = $_FILES['avatar'];
if ($uploadFile['error'] === UPLOAD_ERR_OK) {
$ext = pathinfo($uploadFile['name'], PATHINFO_EXTENSION);
$filename = md5($email) . '.png';
$destination = UPLOAD_DIR . $filename;
if (convertImage($uploadFile['tmp_name'], $destination)) {
$userCodes = json_decode(file_get_contents(USER_EMAIL_CODE_FILE), true);
$userCodes[$email]['avatar'] = $destination;
file_put_contents(USER_EMAIL_CODE_FILE, json_encode($userCodes, JSON_PRETTY_PRINT));
echo "<script>alert('头像上传成功!');</script>";
} else {
echo "<script>alert('头像处理失败!');</script>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户中心</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
.avatar-preview { width: 80px; height: 80px; border: 1px solid #ddd; margin: 10px 0; }
input[type="file"] { margin: 10px 0; }
button { padding: 10px 20px; background: #007cba; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:hover { background: #005a87; }
</style>
</head>
<body>
<h2>用户中心 - <?php echo htmlspecialchars($email); ?></h2>
<h3>当前头像</h3>
<img src="?api=<?php echo urlencode($email); ?>" class="avatar-preview" alt="当前头像">
<h3>上传新头像</h3>
<form method="post" enctype="multipart/form-data">
<input type="file" name="avatar" accept="image/*" required>
<br>
<button type="submit">上传头像</button>
</form>
<h3>API调用</h3>
<p>您的头像API地址:</p>
<code><?php echo $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']; ?>?api=<?php echo urlencode($email); ?></code>
</body>
</html>
<?php
exit;
}
// 管理系统
if ($action === 'admin') {
// 登录检查
if (!isset($_SESSION['admin_logged_in'])) {
if ($_POST && $_POST['password'] === ADMIN_PASSWORD) {
$_SESSION['admin_logged_in'] = true;
} else {
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>管理员登录</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 200px auto; padding: 20px; }
input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; }
button { width: 100%; padding: 10px; background: #007cba; color: white; border: none; border-radius: 5px; cursor: pointer; }
</style>
</head>
<body>
<h2>管理员登录</h2>
<form method="post">
<input type="password" name="password" placeholder="请输入管理员密码" required>
<button type="submit">登录</button>
</form>
</body>
</html>
<?php
exit;
}
}
// 处理各种管理操作
if ($_POST) {
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'upload_default':
if (isset($_FILES['default_avatar']) && $_FILES['default_avatar']['error'] === UPLOAD_ERR_OK) {
$filename = 'default_' . time() . '.png';
$destination = UPLOAD_DIR . $filename;
if (convertImage($_FILES['default_avatar']['tmp_name'], $destination)) {
$picLinks = json_decode(file_get_contents(PIC_LINK_FILE), true);
$picLinks[] = $destination;
file_put_contents(PIC_LINK_FILE, json_encode($picLinks, JSON_PRETTY_PRINT));
echo "<script>alert('默认头像添加成功!');</script>";
}
}
break;
case 'save_smtp':
$config = [
'smtp_host' => $_POST['smtp_host'],
'smtp_port' => $_POST['smtp_port'],
'smtp_username' => $_POST['smtp_username'],
'smtp_password' => $_POST['smtp_password'],
'from_email' => $_POST['from_email'],
'from_name' => $_POST['from_name']
];
file_put_contents(CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT));
echo "<script>alert('SMTP配置保存成功!');</script>";
break;
case 'delete_avatar':
$index = $_POST['index'];
$picLinks = json_decode(file_get_contents(PIC_LINK_FILE), true);
if (isset($picLinks[$index])) {
if (file_exists($picLinks[$index])) {
unlink($picLinks[$index]);
}
array_splice($picLinks, $index, 1);
file_put_contents(PIC_LINK_FILE, json_encode(array_values($picLinks), JSON_PRETTY_PRINT));
echo "<script>alert('头像删除成功!');</script>";
}
break;
}
}
}
$config = json_decode(file_get_contents(CONFIG_FILE), true);
$picLinks = json_decode(file_get_contents(PIC_LINK_FILE), true);
$userCodes = json_decode(file_get_contents(USER_EMAIL_CODE_FILE), true);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>头像系统管理</title>
<style>
body { font-family: Arial, sans-serif; max-width: 1000px; margin: 20px auto; padding: 20px; }
.section { margin: 30px 0; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
input, textarea { width: 100%; padding: 8px; margin: 5px 0; border: 1px solid #ddd; border-radius: 3px; }
button { padding: 10px 20px; background: #007cba; color: white; border: none; border-radius: 3px; cursor: pointer; margin: 5px; }
button:hover { background: #005a87; }
.avatar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 10px; margin: 20px 0; }
.avatar-item { text-align: center; }
.avatar-item img { width: 80px; height: 80px; border: 1px solid #ddd; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
.logout { float: right; background: #dc3545; }
.logout:hover { background: #c82333; }
</style>
</head>
<body>
<h1>头像系统管理</h1>
<a href="?logout" class="logout" style="text-decoration: none; color: white; padding: 10px 20px; border-radius: 3px;">退出登录</a>
<div class="section">
<h2>系统信息</h2>
<p><strong>API地址:</strong><?php echo $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']; ?>?api=用户邮箱</p>
<p><strong>用户申领地址:</strong><?php echo $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']; ?>?email_code</p>
<p><strong>默认头像数量:</strong><?php echo count($picLinks); ?></p>
<p><strong>用户数量:</strong><?php echo count($userCodes); ?></p>
</div>
<div class="section">
<h2>SMTP配置</h2>
<form method="post">
<input type="hidden" name="action" value="save_smtp">
<input type="text" name="smtp_host" placeholder="SMTP主机" value="<?php echo htmlspecialchars($config['smtp_host']); ?>" required>
<input type="number" name="smtp_port" placeholder="SMTP端口" value="<?php echo $config['smtp_port']; ?>" required>
<input type="text" name="smtp_username" placeholder="SMTP用户名" value="<?php echo htmlspecialchars($config['smtp_username']); ?>" required>
<input type="password" name="smtp_password" placeholder="SMTP密码" value="<?php echo htmlspecialchars($config['smtp_password']); ?>" required>
<input type="email" name="from_email" placeholder="发件人邮箱" value="<?php echo htmlspecialchars($config['from_email']); ?>" required>
<input type="text" name="from_name" placeholder="发件人名称" value="<?php echo htmlspecialchars($config['from_name']); ?>" required>
<button type="submit">保存SMTP配置</button>
</form>
</div>
<div class="section">
<h2>默认头像管理</h2>
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="action" value="upload_default">
<input type="file" name="default_avatar" accept="image/*" required>
<button type="submit">添加默认头像</button>
</form>
<div class="avatar-grid">
<?php foreach ($picLinks as $index => $avatar): ?>
<div class="avatar-item">
<img src="<?php echo $avatar; ?>" alt="默认头像">
<form method="post" style="margin: 5px 0;">
<input type="hidden" name="action" value="delete_avatar">
<input type="hidden" name="index" value="<?php echo $index; ?>">
<button type="submit" style="background: #dc3545; font-size: 12px; padding: 5px;">删除</button>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="section">
<h2>用户管理</h2>
<table>
<tr>
<th>邮箱</th>
<th>验证状态</th>
<th>头像</th>
<th>网站</th>
<th>注册时间</th>
</tr>
<?php foreach ($userCodes as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td><?php echo isset($user['verified']) && $user['verified'] ? '已验证' : '未验证'; ?></td>
<td>
<?php if (isset($user['avatar'])): ?>
<img src="<?php echo $user['avatar']; ?>" style="width: 40px; height: 40px;">
<?php else: ?>
无
<?php endif; ?>
</td>
<td><?php echo isset($user['website']) ? htmlspecialchars($user['website']) : '无'; ?></td>
<td><?php echo date('Y-m-d H:i:s', $user['timestamp']); ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
</body>
</html>
<?php
}
// 退出登录
if (isset($_GET['logout'])) {
session_destroy();
header('Location: ' . $_SERVER['SCRIPT_NAME']);
exit;
}
?>