From 45af503e015d4eb67f699ae63ed754e0c8840c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=BD=E6=97=A5=E9=9F=B3=E4=B9=90?= Date: Wed, 24 Sep 2025 14:15:03 +0000 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.php | 43 ++++ db_config.php | 21 ++ db_connect.php | 56 +++++ delete_recommendation.php | 44 ++++ forgot_password.php | 432 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 596 insertions(+) create mode 100644 config.php create mode 100644 db_config.php create mode 100644 db_connect.php create mode 100644 delete_recommendation.php create mode 100644 forgot_password.php diff --git a/config.php b/config.php new file mode 100644 index 0000000..4d6004d --- /dev/null +++ b/config.php @@ -0,0 +1,43 @@ +connect_error) { + // 返回错误信息而非直接终止 + return [ + 'success' => false, + 'error' => '连接失败: ' . $conn->connect_error . + '
服务器: ' . $db_host . + '
用户名: ' . $db_user . + '
数据库: ' . $db_name + ]; + } + + return [ + 'success' => true, + 'connection' => $conn + ]; + } +?> \ No newline at end of file diff --git a/db_config.php b/db_config.php new file mode 100644 index 0000000..5a47ee3 --- /dev/null +++ b/db_config.php @@ -0,0 +1,21 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, +]; + +try { + $conn = new PDO($dsn, $user, $pass, $options); +} catch (\PDOException $e) { + throw new \PDOException($e->getMessage(), (int)$e->getCode()); +} +?> diff --git a/db_connect.php b/db_connect.php new file mode 100644 index 0000000..57b4cbe --- /dev/null +++ b/db_connect.php @@ -0,0 +1,56 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false + ] + ); +} catch(PDOException $e) { + // 记录连接错误 + $logMsg = date('[Y-m-d H:i:s] ') . "数据库连接错误: " . $e->getMessage() . "\n"; + file_put_contents('db_error.log', $logMsg, FILE_APPEND); + $pdo = false; +} + +// 如果数据库不存在,尝试创建(仅用于开发环境) +if ($pdo && !isset($e)) { + try { + // 检查recommendations表是否存在,如果不存在则创建 + $tableCheck = $pdo->query("SHOW TABLES LIKE 'recommendations'"); + if ($tableCheck->rowCount() === 0) { + $createTableSql = " + CREATE TABLE recommendations ( + id INT AUTO_INCREMENT PRIMARY KEY, + song_name VARCHAR(255) NOT NULL, + artist_name VARCHAR(255) NOT NULL, + reason TEXT, + file_path VARCHAR(512) NOT NULL, + status TINYINT NOT NULL DEFAULT 0 COMMENT '0:待审核,1:已同意,2:已驳回', + created_at DATETIME NOT NULL, + reviewed_at DATETIME NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"; + + $pdo->exec($createTableSql); + } + } catch(PDOException $e) { + $logMsg = date('[Y-m-d H:i:s] ') . "表创建错误: " . $e->getMessage() . "\n"; + file_put_contents('db_error.log', $logMsg, FILE_APPEND); + } +} +?> + \ No newline at end of file diff --git a/delete_recommendation.php b/delete_recommendation.php new file mode 100644 index 0000000..bf07e6c --- /dev/null +++ b/delete_recommendation.php @@ -0,0 +1,44 @@ +prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + + // 执行删除 + $result = $stmt->execute(); + + if ($result && $stmt->rowCount() > 0) { + header("Location: $adminHome?delete_status=success&msg=推荐已成功删除"); + } else { + header("Location: $adminHome?delete_status=error&msg=删除失败,推荐不存在或已被删除"); + } + } catch(PDOException $e) { + // 记录错误日志 + $logMsg = date('[Y-m-d H:i:s] ') . "删除推荐错误: " . $e->getMessage() . "\n"; + file_put_contents('db_error.log', $logMsg, FILE_APPEND); + + header("Location: $adminHome?delete_status=error&msg=数据库错误,请稍后再试"); + } +} else { + header("Location: $adminHome?delete_status=error&msg=数据库连接失败"); +} + +exit; +?> \ No newline at end of file diff --git a/forgot_password.php b/forgot_password.php new file mode 100644 index 0000000..9deb2da --- /dev/null +++ b/forgot_password.php @@ -0,0 +1,432 @@ +query($sql)) { + return "创建密码重置表失败: " . $conn->error; + } + return true; + } + + // 生成随机令牌 + function generateToken() { + return bin2hex(random_bytes(32)); + } + + // 使用QQ SMTP发送密码重置邮件 + function sendResetEmailViaQQSMTP($toEmail, $resetLink, $smtpHost, $smtpPort, $smtpUsername, $smtpPassword, $fromName) { + // 邮件主题 + $subject = "=?UTF-8?B?" . base64_encode("密码重置请求 - 音乐分享网站") . "?="; + + // 邮件内容 + $message = ' + + + + + 密码重置请求 - 音乐分享网站 + + + + + + + +
+ + + + + + + + +
+ + + '; + + // 创建邮件头部 + $headers = [ + 'From' => $fromName . " <" . $smtpUsername . ">", + 'Reply-To' => $smtpUsername, + 'X-Mailer' => 'PHP/' . phpversion(), + 'MIME-Version' => '1.0', + 'Content-Type' => 'text/html; charset=UTF-8' + ]; + + // 组装头部字符串 + $headerString = ""; + foreach ($headers as $key => $value) { + $headerString .= $key . ": " . $value . "\r\n"; + } + + // 使用stream_socket_client发送邮件 + $socket = stream_socket_client( + 'ssl://' . $smtpHost . ':' . $smtpPort, + $errorNumber, + $errorMessage, + 30, + STREAM_CLIENT_CONNECT + ); + + if (!$socket) { + throw new Exception("无法连接到SMTP服务器: $errorMessage ($errorNumber)"); + } + + // 发送SMTP命令 + fwrite($socket, "EHLO " . gethostname() . "\r\n"); + fread($socket, 1024); + + fwrite($socket, "AUTH LOGIN\r\n"); + fread($socket, 1024); + + fwrite($socket, base64_encode($smtpUsername) . "\r\n"); + fread($socket, 1024); + + fwrite($socket, base64_encode($smtpPassword) . "\r\n"); + fread($socket, 1024); + + fwrite($socket, "MAIL FROM: <" . $smtpUsername . ">\r\n"); + fread($socket, 1024); + + fwrite($socket, "RCPT TO: <" . $toEmail . ">\r\n"); + fread($socket, 1024); + + fwrite($socket, "DATA\r\n"); + fread($socket, 1024); + + fwrite($socket, "Subject: " . $subject . "\r\n"); + fwrite($socket, $headerString . "\r\n"); + fwrite($socket, $message . "\r\n"); + fwrite($socket, ".\r\n"); + fread($socket, 1024); + + fwrite($socket, "QUIT\r\n"); + fread($socket, 1024); + fclose($socket); + + return true; + } + + // 处理表单提交 + if ($_SERVER["REQUEST_METHOD"] == "POST") { + $email = trim($_POST['email'] ?? ''); + + if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) { + $message = "请输入有效的邮箱地址"; + $messageType = "error"; + } else { + $conn = new mysqli($servername, $dbusername, $dbpassword, $dbname); + if ($conn->connect_error) { + throw new Exception("数据库连接失败: " . $conn->connect_error); + } + + $tableCheck = ensurePasswordResetTableExists($conn); + if ($tableCheck !== true) { + throw new Exception($tableCheck); + } + + $stmt = $conn->prepare("SELECT id FROM users WHERE email = ?"); + if (!$stmt) { + throw new Exception("准备查询语句失败: " . $conn->error); + } + + $stmt->bind_param("s", $email); + $stmt->execute(); + $stmt->store_result(); + + if ($stmt->num_rows == 1) { + $stmt->bind_result($userId); + $stmt->fetch(); + $token = generateToken(); + $expiry = date('Y-m-d H:i:s', strtotime('+1 hour')); + + $updateStmt = $conn->prepare("INSERT INTO password_reset_tokens (user_id, token, expiry) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE token = ?, expiry = ?"); + if (!$updateStmt) { + throw new Exception("准备更新语句失败: " . $conn->error); + } + + $updateStmt->bind_param("issss", $userId, $token, $expiry, $token, $expiry); + $updateStmt->execute(); + + // 生成重置链接 + $resetLink = "http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . "/reset_password.php?token=" . $token; + + try { + // 发送重置邮件 + sendResetEmailViaQQSMTP( + $email, + $resetLink, + $smtpHost, + $smtpPort, + $smtpUsername, + $smtpPassword, + $fromName + ); + + $message = "密码重置链接已发送到您的邮箱,请查收(1小时内有效)"; + $messageType = "success"; + } catch (Exception $e) { + $message = "邮件发送失败: " . $e->getMessage(); + $messageType = "error"; + error_log("邮件发送错误: " . $e->getMessage()); + } + + $updateStmt->close(); + } else { + // 安全考虑,无论邮箱是否存在,都显示相同的成功消息 + $message = "如果该邮箱已注册,密码重置链接将发送"; + $messageType = "success"; + } + $stmt->close(); + $conn->close(); + } + } +} catch (Exception $e) { + $message = "系统错误: " . $e->getMessage(); + $messageType = "error"; + error_log("Forgot Password Error: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine()); +} +?> + + + + + + 忘记密码 - 音乐分享网站 + + + + +
+

忘记密码

+ +
+ +
+ +
+
+ + +
+ +
+ +
+ + + \ No newline at end of file