简体   繁体   中英

PHP - Add users as friends

I have a social website, you can add friends. The way it works is like this:

  • click add friend
  • add the user who clicked into a database row, like this in the columns [bob][fred][123123]
  • fred accepts it with the secret in a verification link, via email.
  • this then puts another row in the database the other way round, like this [fred][bob][123123]

I can then determine if they are friends or not and if they have been accepted.

However, this surely isn't the correct way. I am now very unsure of a way of which could be better and run more smoothly.

There is really no right or wrong way, it is what ever you decide to use, at the end of the day it is your code, so whatever you choose and works for you.

However, you are quite correct, entering two rows would be a very heavy overhead and use extra space for seemingly no good reason. A lot more simply you could set another column in your DB:

user_1 | user_2 | accept_code | accepted

user_1 requests to add user_2 as a friend - you set an accept_code creating an entry in the DB. Set your DB structure to set the accepted column to define as false. Then when the row is first created the users are not currently friends.

Using your example: bob requests fred as a friend. You DB would now look like this:

bob | fred | 123123 | false

When user_2 enters the accept_code , then change accepted to true.

bob | fred | 123123 | true

This way, one query will tell you if the two users are friends, instead of two queries to see if you have two matching DB entries.

So for example, bob has added fred, joe and alex as friends, fred and alex have accepted bob as a friend, but joe has not. You DB would look like this:

user_1 | user_2 | accept_code | accepted

bob | fred | 123123 | true

bob | joe | 321321 | false

bob | alex | 789789 | true

So for example, a psuedo select maybe, find all friends for bob:

SELECT user_2 FROM relationships WHERE user_1="bob" AND accepted="true"

The result would be:

fred alex

UPDATE as per the comments:

DB Structure:

user_1 | user_2 | accept_code | accepted

bob | fred | 123 | true

bob | alex | 123 | true

bob | joe | 123 | false

ste | bob | 123 | true

joe | alex | 123 | true

Select statement:

SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'current_user' OR user_2 = 'current_user');

Example 1 - bob logs in, he has requested friends and been requested as a friend:

SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'bob' OR user_2 = 'bob');

The result:

bob | fred | 123 | accepted

bob | alex | 123 | accepted

ste | bob | 123 | accepted

Example 2 - alex logs in, he has never requested and friends but has been requested as a friend:

SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'alex' OR user_2 = 'alex');

The result:

bob | alex | 123 | accepted

joe | alex | 123 | accepted

Example 3 - joe logs in, he has requested a friend and has declined a friend:

SELECT * FROM relationships WHERE accepted = 'true' AND (user_1 = 'joe' OR user_2 = 'joe');

The result:

joe | alex | 123 | accepted

Social networking database relations can become VERY complicated quickly, especially as the traffic scales up and requests flood in. There is great data available out there from the leading sources like Facebook in their developer blogs on how they modified and adjusted their systems to scale as their traffic increased.

There isn't any one right way to create the relationship - it depends on your code structure - but that being said doing your two queries to create a simple one to one relationship and duplicating the data is correctly assumed to be needless extra overhead.

You could create a simple junction table with the ids of the two users, one field holding whom originated the request (int primary key of the user) and the other the one receiving the request for approval (also the int primary key.) You could have another status int field with numerical values that correspond to the status of the relationship.

You should always use numerical keys for your user's identities - you never know how many 'John's will join up! Make sure you have even just a simple 'Users' table of sorts with UserIDs that are unique keys.

UserID|Name
1      Frank
2      John

This could of course contain other info, last name, location, gender, favorite Sylvester Stallone movie etc.

Relationships can be created in a separate relationships table with the following structure... So when Frank (id 1) requests John (id 2), we end up with a row like this.

RelationshipID|RequestedBy|Receipient|RequestStatus|ConfirmationCode
(primary key)       1           2        0            (however you format your url strings)

You could then have a primary key for ALL the relationships. Every individual link would be identifiable.

Also, I personally would integrate another table to define the status variable.

StatusIdentifier|StatusDefinition
0                 Requested but not yet approved
-1                Requested and denied (mark for deletion)
1                 Requested and approved (active friendship)

This way you could extend the types of relationships in the program if you ever wanted more, such as friended then deleted, blocked, etc. In most of the apps I've deployed this kind of data was a good candidate for XML, but there's nothing wrong with throwing it in a database. Responses by the recipient would have to get the RelationshipID and then update this status value.

Adding a timestamp for updates on the relationship table is a good idea too.

Using this structure, you could easily query all the user's friends using their primary id from your user table. Let's get Franks into an array:

$sql = 'SELECT Recipient FROM FriendRelationships WHERE RequestedBy = 1 AND RequestStatus = 1';

This gets all active friend user ids for Frank, since he is the requester (1) and we're limiting to requests that have been approved by the recipient.

hi you can try this logic.

Lets say bob wants to add fred as friend.

  1. bob send fred to add as friend

    Action: there is will database lookup table as friends: [bob] [fred] [hide-only make it visible when bob accepts it]

  2. fred accepts the request after validation Action: make the [hide] ---> [ visible]

    Now you have relation with user's and friends.[each row in lookup table is friends]

    hope this will be helpful

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM