我最近清理了我的网络应用程序的代码。我的网络应用程序是一个简单的社交网络,具有添加,删除等过程。我有一个php文件,当用户想要从他的朋友列表中删除联系人时,我会调用该文件。
我在应用程序中发现了一个奇怪的错误,我没有估计我编写它的时间。
虫子
假设我们的列表中有两封好友电子邮件。
- georgeMARK@email.com
- MARK@email.com
联系人电子邮件存储在名称为Contacts
的MYSQL DB列中,每封电子邮件都用分号(;
)符号分隔。因此,我们示例的列将如下所示(取决于最后添加的用户,反之亦然):
georgeMARK@email.com;MARK@email.com;
因此,假设我们的用户想要从他的联系人中删除MARK
。他按下按钮并...两封电子邮件都消失了。!
看看我的 PHPMyAdmin 面板,我发现该列留下的是这样的:
george
问题出在我用来从列中删除帐户的 PDO SQL 语句中。
$STH = $DHB->prepare("UPDATE `Users` SET `Contacts` = REPLACE(`Contacts`, :email, '') WHERE `UserEmail` = :my_email");
REPLACE
函数只是替换了:email
的所有实例,这很糟糕。我在应用程序中多次使用相同的方法,我知道这会导致我的相同错误也出现在其他地方。
我的问题是如何在不影响其他"实例"的情况下删除用户的电子邮件?我是否必须改变我的观点,我需要怎么做?
快速脏的方法是在所有联系人字段中加上一个分号,以便条目如下所示:
;georgeMARK@email.com;MARK@email.com;
然后你可以这样替换它:
$emailToDelete = ";$emailToDelete;"
... REPLACE(`Contacts`, :email, ';') ...
更好的方法是以更合适的格式(如 JSON)存储联系人数据。
最好的解决方案是创建一个关系表,并删除与要删除的联系人相关的所有条目。
结构
也许创建一个这样的结构:
表用户
id | Name | Email
-----------------
1 | John | john@example.com
2 | Jane | jane@example2.com
餐桌友谊
User1_id | User2_id
-------------------
1 | 2
选择用户
SELECT * FROM Users WHERE name=:name
选择好友
SELECT
*
FROM
Friendships
LEFT JOIN
Users
ON
Friendships.User1_id = Users.id
WHERE
User1_id=:user_id
删除友谊
DELETE FROM Friendships WHERE User1_id=:current_user_id AND User2_id=:friend_to_remove_id