小狗跑跑
空格跳跃躲障碍。
分数:0 | 最高分:0
PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); return $pdo; } function jsonResponse(array $data, int $code = 200): void { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE); exit; } function jsonInput(): array { $raw = file_get_contents('php://input'); if (!is_string($raw) || trim($raw) === '') { return []; } $data = json_decode($raw, true, 512, JSON_INVALID_UTF8_SUBSTITUTE); return is_array($data) ? $data : []; } function hashToken(string $token): string { return hash('sha256', $token); } $allowedCategories = ['学习压力', '工作烦恼', '今日开心', '情绪树洞', '日常分享']; if (isset($_GET['endpoint']) && $_GET['endpoint'] === 'posts') { try { $pdo = getPDO(); } catch (Throwable $e) { jsonResponse(['ok' => false, 'message' => '数据库连接失败,请检查配置。'], 500); } if ($_SERVER['REQUEST_METHOD'] === 'GET') { try { $page = max((int)($_GET['page'] ?? 1), 1); $pageSize = 10; $offset = ($page - 1) * $pageSize; $authorToken = trim((string)($_GET['author_token'] ?? '')); $tokenHash = $authorToken !== '' ? hashToken($authorToken) : ''; $total = (int)$pdo->query('SELECT COUNT(*) FROM posts')->fetchColumn(); $totalPages = max((int)ceil($total / $pageSize), 1); $stmt = $pdo->prepare( 'SELECT id, nickname, category, content, reply_to_id, likes_count, author_token_hash, created_at FROM posts ORDER BY created_at DESC LIMIT :limit OFFSET :offset' ); $stmt->bindValue(':limit', $pageSize, PDO::PARAM_INT); $stmt->bindValue(':offset', $offset, PDO::PARAM_INT); $stmt->execute(); $rows = $stmt->fetchAll(); $posts = array_map(static function (array $row) use ($tokenHash): array { $row['can_delete'] = $tokenHash !== '' && hash_equals((string)$row['author_token_hash'], $tokenHash); unset($row['author_token_hash']); return $row; }, $rows); jsonResponse(['ok' => true, 'data' => $posts, 'pagination' => ['page' => $page, 'total_pages' => $totalPages]]); } catch (Throwable $e) { jsonResponse(['ok' => false, 'message' => '请先导入 SQL 脚本,或确认 posts 表存在。'], 500); } } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $payload = jsonInput(); $action = (string)($payload['action'] ?? 'create'); if ($action === 'like') { $id = (int)($payload['id'] ?? 0); if ($id <= 0) { jsonResponse(['ok' => false, 'message' => '留言 ID 无效。'], 422); } $stmt = $pdo->prepare('UPDATE posts SET likes_count = likes_count + 1 WHERE id = :id'); $stmt->execute([':id' => $id]); jsonResponse(['ok' => true, 'message' => '已点赞']); } if ($action === 'delete') { $id = (int)($payload['id'] ?? 0); $authorToken = trim((string)($payload['author_token'] ?? '')); if ($id <= 0 || $authorToken === '') { jsonResponse(['ok' => false, 'message' => '删除参数不完整。'], 422); } $stmt = $pdo->prepare('DELETE FROM posts WHERE id = :id AND author_token_hash = :token_hash'); $stmt->execute([':id' => $id, ':token_hash' => hashToken($authorToken)]); if ($stmt->rowCount() === 0) { jsonResponse(['ok' => false, 'message' => '只能删除自己发布的留言。'], 403); } jsonResponse(['ok' => true, 'message' => '留言已删除']); } $nickname = trim((string)($payload['nickname'] ?? '匿名小狗')); $category = trim((string)($payload['category'] ?? '日常分享')); $content = trim((string)($payload['content'] ?? '')); $replyToId = isset($payload['reply_to_id']) ? (int)$payload['reply_to_id'] : null; $authorToken = trim((string)($payload['author_token'] ?? '')); if ($content === '') { jsonResponse(['ok' => false, 'message' => '留言内容不能为空。'], 422); } if (mb_strlen($nickname) > 20 || mb_strlen($nickname) < 1) { jsonResponse(['ok' => false, 'message' => '昵称长度需在 1-20 个字符。'], 422); } if (!in_array($category, $allowedCategories, true)) { jsonResponse(['ok' => false, 'message' => '留言分类不合法。'], 422); } if (mb_strlen($content) > 300) { jsonResponse(['ok' => false, 'message' => '留言内容最多 300 个字符。'], 422); } if ($authorToken === '' || mb_strlen($authorToken) > 64) { jsonResponse(['ok' => false, 'message' => '作者令牌无效。'], 422); } if ($replyToId !== null && $replyToId <= 0) { $replyToId = null; } $stmt = $pdo->prepare( 'INSERT INTO posts (nickname, category, content, reply_to_id, likes_count, author_token_hash, created_at) VALUES (:nickname, :category, :content, :reply_to_id, 0, :author_token_hash, NOW())' ); $stmt->execute([ ':nickname' => $nickname, ':category' => $category, ':content' => $content, ':reply_to_id' => $replyToId, ':author_token_hash' => hashToken($authorToken), ]); jsonResponse(['ok' => true, 'message' => '留言发布成功!']); } jsonResponse(['ok' => false, 'message' => '不支持的请求方式。'], 405); } ?>
淡蓝治愈风 + 小狗元素 + 互动交流 + 解压小游戏。
每一次停下来呼吸,都是在照顾自己。
空格跳跃躲障碍。
分数:0 | 最高分:0
点击同色连通块,3个以上消除。
得分:0 | 最高分:0
社交区
查看全部留言,点赞、回复、删除自己的留言。
加载中...