上传文件至 /
This commit is contained in:
466
profile.php
Normal file
466
profile.php
Normal file
@@ -0,0 +1,466 @@
|
||||
<?php
|
||||
// 错误处理设置
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// 初始化变量
|
||||
$message = '';
|
||||
$messageType = '';
|
||||
$userId = 0;
|
||||
$currentNickname = '未设置';
|
||||
$currentEmail = '未设置';
|
||||
$ossConfigured = false;
|
||||
$avatarUrl = './static/icon/icon.png';
|
||||
$ossLoaded = false;
|
||||
|
||||
try {
|
||||
session_start();
|
||||
|
||||
// 检查登录状态
|
||||
if (!isset($_SESSION['user_logged_in']) || $_SESSION['user_logged_in'] !== true) {
|
||||
throw new Exception("请先<a href='login.php'>登录</a>");
|
||||
}
|
||||
|
||||
// 获取用户ID
|
||||
if (isset($_SESSION['user_id']) && is_numeric($_SESSION['user_id'])) {
|
||||
$userId = (int)$_SESSION['user_id'];
|
||||
} else {
|
||||
throw new Exception("无法获取用户ID,请重新登录");
|
||||
}
|
||||
|
||||
// 加载配置文件
|
||||
$config = [];
|
||||
$configFile = 'pmconfig.php';
|
||||
if (file_exists($configFile)) {
|
||||
$config = include $configFile;
|
||||
if (!is_array($config)) {
|
||||
throw new Exception("配置文件必须返回一个数组");
|
||||
}
|
||||
} else {
|
||||
throw new Exception("配置文件 pmconfig.php 不存在");
|
||||
}
|
||||
|
||||
// 检查OSS配置
|
||||
$ossParams = ['oss_access_key', 'oss_secret_key', 'oss_endpoint', 'oss_bucket'];
|
||||
$missingOssParams = [];
|
||||
foreach ($ossParams as $param) {
|
||||
if (!isset($config[$param]) || empty($config[$param])) {
|
||||
$missingOssParams[] = $param;
|
||||
}
|
||||
}
|
||||
$ossConfigured = empty($missingOssParams);
|
||||
|
||||
// 引入OSS SDK
|
||||
if ($ossConfigured) {
|
||||
$ossSdkPath = __DIR__ . '/oss-sdk/autoload.php';
|
||||
if (file_exists($ossSdkPath) && is_readable($ossSdkPath)) {
|
||||
require_once $ossSdkPath;
|
||||
$ossLoaded = class_exists('OSS\OssClient') && class_exists('OSS\Core\OssException');
|
||||
}
|
||||
}
|
||||
|
||||
// 生成头像URL
|
||||
if ($ossConfigured && $ossLoaded) {
|
||||
$bucket = $config['oss_bucket'];
|
||||
$endpoint = preg_replace('/^https?:\/\//', '', $config['oss_endpoint']);
|
||||
$object = 'sunmusic/profile/' . $userId . '头像.png';
|
||||
$avatarUrl = "https://{$bucket}.{$endpoint}/{$object}?t=" . time();
|
||||
}
|
||||
|
||||
// 数据库连接和用户信息获取
|
||||
$dbRequired = ['db_host', 'db_user', 'db_name'];
|
||||
$dbMissing = [];
|
||||
foreach ($dbRequired as $param) {
|
||||
if (!isset($config[$param]) || empty($config[$param])) {
|
||||
$dbMissing[] = $param;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($dbMissing)) {
|
||||
$conn = new mysqli(
|
||||
$config['db_host'],
|
||||
$config['db_user'],
|
||||
$config['db_pass'] ?? '',
|
||||
$config['db_name']
|
||||
);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
throw new Exception("数据库连接失败: " . $conn->connect_error);
|
||||
}
|
||||
|
||||
$conn->set_charset("utf8mb4");
|
||||
|
||||
// 获取用户信息
|
||||
$stmt = $conn->prepare("SELECT nickname, email FROM users WHERE id = ?");
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($userData = $result->fetch_assoc()) {
|
||||
$currentNickname = $userData['nickname'] ?? '未设置';
|
||||
$currentEmail = $userData['email'] ?? '未设置';
|
||||
} else {
|
||||
throw new Exception("未找到用户信息");
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
// 处理基础信息更新
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_basic'])) {
|
||||
$newNickname = trim($_POST['nickname'] ?? '');
|
||||
$newEmail = trim($_POST['email'] ?? '');
|
||||
|
||||
$updates = [];
|
||||
$params = [];
|
||||
$types = '';
|
||||
|
||||
if (!empty($newNickname) && $newNickname !== $currentNickname) {
|
||||
if (strlen($newNickname) < 2 || strlen($newNickname) > 20) {
|
||||
throw new Exception("用户名长度必须在2-20个字符之间");
|
||||
}
|
||||
$updates[] = "nickname = ?";
|
||||
$params[] = $newNickname;
|
||||
$types .= "s";
|
||||
}
|
||||
|
||||
if (!empty($newEmail) && $newEmail !== $currentEmail) {
|
||||
if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Exception("请输入有效的邮箱地址");
|
||||
}
|
||||
|
||||
// 检查邮箱是否已被使用
|
||||
$checkStmt = $conn->prepare("SELECT id FROM users WHERE email = ? AND id != ?");
|
||||
$checkStmt->bind_param("si", $newEmail, $userId);
|
||||
$checkStmt->execute();
|
||||
$checkResult = $checkStmt->get_result();
|
||||
|
||||
if ($checkResult->num_rows > 0) {
|
||||
throw new Exception("该邮箱已被其他用户使用");
|
||||
}
|
||||
|
||||
$checkStmt->close();
|
||||
|
||||
$updates[] = "email = ?";
|
||||
$params[] = $newEmail;
|
||||
$types .= "s";
|
||||
}
|
||||
|
||||
if (!empty($updates)) {
|
||||
$sql = "UPDATE users SET " . implode(", ", $updates) . " WHERE id = ?";
|
||||
$types .= "i";
|
||||
$params[] = $userId;
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$bindParams = array_merge([$types], $params);
|
||||
$tmp = [];
|
||||
foreach ($bindParams as $key => $value) {
|
||||
$tmp[$key] = &$bindParams[$key];
|
||||
}
|
||||
call_user_func_array([$stmt, 'bind_param'], $tmp);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
$currentNickname = $newNickname;
|
||||
$currentEmail = $newEmail;
|
||||
$message = "信息更新成功";
|
||||
$messageType = 'success';
|
||||
} else {
|
||||
$message = "没有需要更新的信息";
|
||||
$messageType = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
} else {
|
||||
throw new Exception("数据库配置不完整(缺少: " . implode(', ', $dbMissing) . ")");
|
||||
}
|
||||
|
||||
// 处理头像上传
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_avatar']) && $ossConfigured && $ossLoaded) {
|
||||
if (!isset($_FILES['avatar'])) {
|
||||
throw new Exception("未收到上传文件");
|
||||
}
|
||||
|
||||
// 检查上传错误
|
||||
switch ($_FILES['avatar']['error']) {
|
||||
case UPLOAD_ERR_OK:
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
throw new Exception("请选择要上传的图片");
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
throw new Exception("文件过大,超过上传限制");
|
||||
default:
|
||||
throw new Exception("上传错误,代码: " . $_FILES['avatar']['error']);
|
||||
}
|
||||
|
||||
$avatarFile = $_FILES['avatar'];
|
||||
|
||||
// 验证文件
|
||||
if (!is_uploaded_file($avatarFile['tmp_name'])) {
|
||||
throw new Exception("文件上传异常");
|
||||
}
|
||||
|
||||
$fileInfo = getimagesize($avatarFile['tmp_name']);
|
||||
if (!$fileInfo) {
|
||||
throw new Exception("不是有效的图片文件");
|
||||
}
|
||||
|
||||
$allowedMime = ['image/jpeg', 'image/png', 'image/gif'];
|
||||
if (!in_array($fileInfo['mime'], $allowedMime)) {
|
||||
throw new Exception("不支持的图片类型");
|
||||
}
|
||||
|
||||
if ($avatarFile['size'] > 10 * 1024 * 1024) {
|
||||
throw new Exception("文件过大,最大支持10MB");
|
||||
}
|
||||
|
||||
// OSS上传
|
||||
$object = 'sunmusic/profile/' . $userId . '头像.png';
|
||||
try {
|
||||
$ossClient = new OSS\OssClient(
|
||||
$config['oss_access_key'],
|
||||
$config['oss_secret_key'],
|
||||
$config['oss_endpoint']
|
||||
);
|
||||
|
||||
$options = [
|
||||
OSS\OssClient::OSS_HEADERS => [
|
||||
'x-oss-object-acl' => 'public-read',
|
||||
],
|
||||
];
|
||||
|
||||
$ossClient->uploadFile(
|
||||
$config['oss_bucket'],
|
||||
$object,
|
||||
$avatarFile['tmp_name'],
|
||||
$options
|
||||
);
|
||||
|
||||
$endpoint = preg_replace('/^https?:\/\//', '', $config['oss_endpoint']);
|
||||
$avatarUrl = "https://{$config['oss_bucket']}.{$endpoint}/{$object}?t=" . time();
|
||||
$message = "头像上传成功!";
|
||||
$messageType = 'success';
|
||||
} catch (OSS\Core\OssException $e) {
|
||||
throw new Exception("OSS错误: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$message = $e->getMessage();
|
||||
$messageType = 'error';
|
||||
}
|
||||
|
||||
// 检测设备类型
|
||||
$isMobile = preg_match('/(android|iphone|ipad|ipod|blackberry|windows phone)/i', $_SERVER['HTTP_USER_AGENT']);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" class="<?php echo $isMobile ? 'mobile' : 'desktop'; ?>">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>个人信息</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<style>
|
||||
/* === 引入自定义字体 === */
|
||||
@font-face {
|
||||
font-family: "MyCustomFont";
|
||||
src: url("./static/font/bbc.ttf") format("truetype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/* 基础样式 */
|
||||
:root {
|
||||
--bg-color: #f5f5f7;
|
||||
--text-color: #333;
|
||||
--card-bg: #ffffff;
|
||||
--card-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
--primary-color: #2c3e50;
|
||||
--primary-hover: #34495e;
|
||||
--border-color: #ddd;
|
||||
--accent-color: #e74c3c;
|
||||
--main-font: "MyCustomFont", sans-serif; /* 自定义字体变量 */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--main-font);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* 布局样式 */
|
||||
.app-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.profile-container {
|
||||
background-color: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
padding: 2rem;
|
||||
box-shadow: var(--card-shadow);
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* 标题样式 */
|
||||
h1, h2 {
|
||||
color: var(--primary-color);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* 头像样式 */
|
||||
.avatar-container {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 3px solid var(--primary-color);
|
||||
margin: 0 auto 1rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.avatar-upload {
|
||||
margin-top: 1rem;
|
||||
padding: 1.5rem;
|
||||
border: 1px dashed var(--border-color);
|
||||
border-radius: 8px;
|
||||
background-color: rgba(44, 62, 80, 0.03);
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
.form-group {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.submit-btn {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.8rem 2rem;
|
||||
border-radius: 25px;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.submit-btn:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: transparent;
|
||||
color: var(--primary-color);
|
||||
border: 1px solid var(--primary-color);
|
||||
}
|
||||
|
||||
/* 消息提示样式 */
|
||||
.message {
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.success {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<h1>个人信息管理</h1>
|
||||
|
||||
<div class="profile-container">
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="message <?php echo $messageType; ?>"><?php echo $message; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 头像上传区域 -->
|
||||
<div class="avatar-container">
|
||||
<h2>个人头像</h2>
|
||||
<img src="<?php echo htmlspecialchars($avatarUrl); ?>" class="avatar"
|
||||
alt="用户头像" onerror="this.src='./static/icon/icon.png'">
|
||||
|
||||
<div class="avatar-upload">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<input type="file" name="avatar" accept="image/*" class="form-control">
|
||||
<p></p>
|
||||
<button type="submit" name="upload_avatar" class="submit-btn"
|
||||
<?php echo !$ossConfigured ? 'disabled title="OSS配置不完整,无法上传"' : ''; ?>>
|
||||
上传头像
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 个人信息编辑区域 -->
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="nickname">用户名</label>
|
||||
<input type="text" id="nickname" name="nickname"
|
||||
value="<?php echo htmlspecialchars($currentNickname); ?>"
|
||||
class="form-control" maxlength="20">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">电子邮箱</label>
|
||||
<input type="email" id="email" name="email"
|
||||
value="<?php echo htmlspecialchars($currentEmail); ?>"
|
||||
class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="index.php" class="submit-btn btn-secondary">返回</a>
|
||||
<button type="submit" name="update_basic" class="submit-btn">保存修改</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user