php实现笔记共享
PHP实现笔记共享的基本方法
数据库设计
创建数据库表存储笔记信息,例如notes表包含字段:id(主键)、title、content、user_id(创建者)、created_at、updated_at。共享功能需要额外表note_shares,包含字段:id、note_id、user_id(被共享用户)、permission(读写权限)。
用户认证系统 使用PHP会话或JWT实现用户登录验证。共享笔记前需验证当前用户是否有权限操作该笔记。
// 示例:检查笔记所有权
function checkNoteOwnership($noteId, $userId) {
$stmt = $pdo->prepare("SELECT user_id FROM notes WHERE id = ?");
$stmt->execute([$noteId]);
return $stmt->fetchColumn() == $userId;
}
共享功能实现
通过表单或API接收被共享用户ID和权限级别,插入到note_shares表。
// 示例:共享笔记
function shareNote($noteId, $sharedUserId, $permission) {
$stmt = $pdo->prepare("INSERT INTO note_shares (note_id, user_id, permission) VALUES (?, ?, ?)");
return $stmt->execute([$noteId, $sharedUserId, $permission]);
}
前端界面构建
笔记列表展示 查询用户自有笔记和共享笔记,合并显示。区分不同权限的笔记(只读/可编辑)。
// 示例:获取用户可见笔记
function getUserNotes($userId) {
$stmt = $pdo->prepare("
SELECT n.*, ns.permission
FROM notes n
LEFT JOIN note_shares ns ON n.id = ns.note_id
WHERE n.user_id = ? OR ns.user_id = ?
");
$stmt->execute([$userId, $userId]);
return $stmt->fetchAll();
}
共享管理界面 提供界面让用户查看当前共享状态,支持取消共享或修改权限。

实时协作扩展
WebSocket实现 使用Ratchet或Swoole实现实时同步。当笔记内容变更时,推送更新给所有正在查看该笔记的用户。
// 示例:WebSocket消息处理
$loop = React\EventLoop\Factory::create();
$webSocket = new Ratchet\WebSocket\WsServer(new NoteCollaborationServer());
$server = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer($webSocket),
$loop
);
$server->run();
冲突解决策略 采用操作转换(OT)或差分同步算法处理多人同时编辑的冲突。记录修改历史,提供版本回退功能。
安全注意事项
输入验证 对所有用户输入进行过滤,防止XSS攻击。使用HTML Purifier处理富文本内容。

// 示例:内容过滤
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$cleanContent = $purifier->purify($userInput);
权限验证 每次笔记访问都验证权限,防止越权访问。API接口需验证JWT或会话有效性。
// 示例:权限中间件
function checkNotePermission($noteId, $userId) {
$stmt = $pdo->prepare("
SELECT 1 FROM notes WHERE id = ? AND user_id = ?
UNION
SELECT 1 FROM note_shares WHERE note_id = ? AND user_id = ?
");
$stmt->execute([$noteId, $userId, $noteId, $userId]);
return $stmt->fetchColumn() !== false;
}
性能优化建议
缓存策略 对频繁访问的笔记内容使用Redis缓存,减少数据库查询压力。
// 示例:缓存笔记内容
function getNoteContent($noteId) {
$cacheKey = "note_content_$noteId";
if ($redis->exists($cacheKey)) {
return $redis->get($cacheKey);
}
$content = fetchNoteFromDB($noteId);
$redis->setex($cacheKey, 3600, $content);
return $content;
}
分页查询 对笔记列表实现分页,避免一次性加载过多数据。使用LIMIT和OFFSET参数。
// 示例:分页查询
function getNotesPaginated($userId, $page, $perPage) {
$offset = ($page - 1) * $perPage;
$stmt = $pdo->prepare("... LIMIT ? OFFSET ?");
$stmt->execute([$perPage, $offset]);
return $stmt->fetchAll();
}






