How To Make Friend Request System in PHP & MySQL

In this step-by-step tutorial you will learn how to create friend request system like Facebook using PHP and MySQL with source code.

Steps to Create this Friend Request System

Before starting, here are the features of this Friend Request System:

  • Login and Sign up.
  • A user can send, accept, ignore, and cancel a friend request.
  • Request Notification.
  • Unfriend a friend.
  • Total number of friends.

Step 1: Create a Database and its Tables

Here is the database info and table structure –

  • Database Name: frnd_req_system
  • Tables:
    • usersid, name, email, password
    • friend_requestssender, receiver
    • friendsuser_one, user_two
  • As reference key: sender, receiver, user_one, user_two – all referencing the Foreign key from the users(id) table.

Use the following SQL code to build the frnd_req_system database structure –

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;


CREATE TABLE `friends` (
  `user_one` int(11) NOT NULL,
  `user_two` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `friend_requests` (
  `sender` int(11) NOT NULL,
  `receiver` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` varchar(30) NOT NULL,
  `email` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;


ALTER TABLE `friends`
  ADD KEY `user_one` (`user_one`),
  ADD KEY `user_two` (`user_two`);

ALTER TABLE `friend_requests`
  ADD KEY `sender` (`sender`),
  ADD KEY `receiver` (`receiver`);

ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `email` (`email`);


ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;


ALTER TABLE `friends`
  ADD CONSTRAINT `friends_ibfk_1` FOREIGN KEY (`user_one`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  ADD CONSTRAINT `friends_ibfk_2` FOREIGN KEY (`user_two`) REFERENCES `users` (`id`) ON DELETE CASCADE;

ALTER TABLE `friend_requests`
  ADD CONSTRAINT `friend_requests_ibfk_1` FOREIGN KEY (`sender`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  ADD CONSTRAINT `friend_requests_ibfk_2` FOREIGN KEY (`receiver`) REFERENCES `users` (`id`) ON DELETE CASCADE;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Alternative database structure:

You can also do the following where you will have only one table to handle the requests –

  • users table:
    • id (Primary key)
    • name
    • Other user-related fields
  • friend_requests table:
    • id (Primary key)
    • sender_id (Foreign key referencing users table)
    • receiver_id (Foreign key referencing users table)
    • status (Pending/Accepted/Rejected)

Step 2: Graphical Explanation of the Working of this System

Graphical explanation of the PHP friend request system

Step 3: Create the Project Folder

Open your xampp htdocs folder or your localhost www directory and in the folder create a new folder called php-friend-request-system this is our project folder. Here is the structure of this folder:

PHP Friend request system folder structure

Step 4: Create PHP Classes for this Application

Now create a new folder called classes at root of the project folder. All the classes will be inside this classes folder.

1. Database.php: Contains the code for database connection.

<?php
class Database
{
    private $db_host = 'localhost';
    private $db_name = 'frnd_req_system';
    private $db_username = 'root'; // add your db user
    private $db_password = ''; // add your db password
    function __construct()
    {
        try {
            $dsn = "mysql:host={$this->db_host};dbname={$this->db_name};charset=utf8";
            $db_connection = new PDO($dsn, $this->db_username, $this->db_password);
            $db_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $db_connection;
        } catch (PDOException $e) {
            echo "Connection error " . $e->getMessage();
            exit;
        }
    }
}

2. User.php: For Login, Register, and Fetch users with validation.

<?php
// Including the Database class
require_once __DIR__ . "/Database.php";

// User class extending Database
class User extends Database
{
    protected $conn; // Database connection object

    // Constructor to establish a database connection
    function __construct()
    {
        $this->conn = parent::__construct(); // Establishing database connection via parent class constructor
    }

    // Method to check if email is valid
    protected function is_valid_email($email)
    {
        // Regular expression to validate email format
        return (!preg_match(
            "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$^",
            $email
        )) ? FALSE : TRUE;
    }

    // Method to validate input fields
    protected function field_validation(array $fields)
    {
        $empty_fields = [];

        // Loop through input fields
        foreach ($fields as $key => $val) {
            if (empty($val)) {
                // Check if field is empty
                $empty_fields[$key] = "Must not be empty.";
            } elseif ($key === "email" && !$this->is_valid_email($val)) {
                // Check if email is invalid
                $empty_fields[$key] = "Invalid email address";
            }
        }

        // Return error message if any field is empty or invalid
        if (count($empty_fields) && (count($empty_fields) <= count($fields))) {
            return [
                "ok" => 0,
                "field_error" => $empty_fields
            ];
        }
        return false;
    }

    // Method to register a user
    function register($name, $email, $password)
    {
        $data = [];
        $data["name"] = trim(htmlspecialchars($name));
        $data["email"] = trim($email);
        $data["password"] = trim($password);

        // Validate input fields
        $errors = $this->field_validation($data);
        if ($errors) return $errors;

        try {
            $email = $data["email"];

            // Check if email already exists
            $query = $this->conn->query("SELECT * FROM `users` WHERE `email`= '$email'");
            if ($query->rowCount() !== 0) {
                return [
                    "ok" => 0,
                    "field_error" => ["email" => "This Email is already registered."]
                ];
            }

            // Hash password
            $password = password_hash($data["password"], PASSWORD_DEFAULT);

            // Insert user data into database
            $sql = "INSERT INTO `users` (`name`, `email`, `password`) VALUES(?,?,?)";
            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(1, $data["name"], PDO::PARAM_STR);
            $stmt->bindParam(2, $data["email"], PDO::PARAM_STR);
            $stmt->bindParam(3, $password, PDO::PARAM_STR);
            $stmt->execute();

            // Return success message
            return [
                "ok" => 1,
                "message" => "You have been registered successfully."
            ];
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }

    // Method to authenticate user login
    function login($email, $password)
    {
        $data = [];
        $data["email"] = trim($email);
        $data["password"] = trim($password);

        // Validate input fields
        $errors = $this->field_validation($data);
        if ($errors) return $errors;

        try {
            // Check if email exists in database
            $query = $this->conn->query("SELECT * FROM `users` WHERE `email`= '{$data["email"]}'");
            if ($query->rowCount() === 0) {
                return [
                    "ok" => 0,
                    "field_error" => ["email" => "This email is not registered."]
                ];
            }

            // Fetch user data
            $user = $query->fetch(PDO::FETCH_ASSOC);

            // Verify password
            $password_match = password_verify($data["password"], $user['password']);
            if (!$password_match) {
                return [
                    "ok" => 0,
                    "field_error" => ["password" => "Incorrect Password."]
                ];
            }

            // Start session and set user id
            $_SESSION['user_id'] = $user["id"];
            header("Location: home.php");
            exit;
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }

    // Method to find a user by ID
    function find_by_id($id)
    {
        if (!filter_var($id, FILTER_VALIDATE_INT)) {
            return false;
        }
        try {
            // Retrieve user data by ID
            $query = $this->conn->query("SELECT `id`, `name`, `email` FROM `users` WHERE `id`= '$id'");
            if ($query->rowCount() === 0) return null;
            return $query->fetch(PDO::FETCH_OBJ);
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }

    // Method to find all users except the specified one
    function find_all_except($id)
    {
        if (!filter_var($id, FILTER_VALIDATE_INT)) {
            return false;
        }

        try {
            // Retrieve all users except the specified one
            $query = $this->conn->query("SELECT `id`, `name`, `email` FROM `users` WHERE `id` != '$id' ORDER BY `id` DESC");
            if ($query->rowCount() === 0) return null;
            return $query->fetchAll(PDO::FETCH_OBJ);
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }
}

3. Friend.php: Handles the friend request actions such as – send, accept, ignore, unfriend, etc.

<?php
// Including the Database class
require_once __DIR__ . "/Database.php";

// Friend class extending Database
class Friend extends Database
{
    protected $conn; // Database connection object
    protected $my_id; // User's own ID
    protected $user_id; // ID of the other user

    // Constructor to establish a database connection
    function __construct()
    {
        $this->conn = parent::__construct(); // Establishing database connection via parent class constructor
    }

    // Method to validate if provided IDs are integers
    protected function id_validation(array $ids)
    {
        foreach ($ids as $val) {
            if (!filter_var($val, FILTER_VALIDATE_INT)) {
                return false;
            }
        }
        return true;
    }

    // Method to run SQL query with specified condition
    protected function run_query($condition, $full_query = false, $table_name = "friend_requests")
    {
        // Validate IDs
        if (!$this->id_validation([$this->my_id, $this->user_id])) return false;

        try {
            // Construct SQL query
            $sql = "SELECT * FROM `$table_name` WHERE $condition";
            if ($full_query) $sql = $full_query;

            // Execute query
            $query = $this->conn->query($sql);
            
            // Check if any result returned
            if ($query->rowCount() === 0) return null;

            return true;
        } catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }

    // Method to redirect to user profile
    protected function profile_redirect()
    {
        header('Location: profile.php?id=' . $this->user_id);
        exit;
    }

    // Method to check if users are already friends
    function is_already_friends($my_id, $user_id)
    {
        $this->my_id = $my_id;
        $this->user_id = $user_id;
        $result = $this->run_query("(`user_one` = '$my_id' AND `user_two` = '$user_id') OR (`user_one` = '$user_id' AND `user_two` = '$my_id')", false, "friends");
        return $result;
    }

    // Method to check if the user is the request sender or receiver
    function am_i_the_req($_, $my_id, $user_id)
    {
        $this->my_id = $my_id;
        $this->user_id = $user_id;
        if ($_ === "sender") {
            return $this->run_query("`sender` = '$my_id' AND `receiver` = '$user_id'");
        } elseif ($_ === "receiver") {
            return $this->run_query("`sender` = '$user_id' AND `receiver` = '$my_id'");
        }
        echo "Parameter must be 'sender' or 'receiver'";
        exit;
    }

    // Method to check if friend request has already been sent
    function is_request_already_sent($my_id, $user_id)
    {
        try {
            $this->my_id = $my_id;
            $this->user_id = $user_id;
            return $this->run_query("(sender = '$my_id' AND receiver = '$user_id') OR (sender = '$user_id' AND receiver = '$my_id')");
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to send friend request
    function pending_friends($my_id, $user_id)
    {
        try {
            $this->my_id = $my_id;
            $this->user_id = $user_id;
            $sql = "INSERT INTO `friend_requests`(`sender`, `receiver`) VALUES('$my_id','$user_id')";
            $this->run_query(NULL, $sql);
            $this->profile_redirect();
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to cancel or ignore friend request
    function cancel_or_ignore_friend_request($my_id, $user_id, $action)
    {
        $this->my_id = $my_id;
        $this->user_id = $user_id;

        if ($action == "cancel") {
            $sql = "DELETE FROM `friend_requests` WHERE `sender` = '$my_id' AND `receiver` = '$user_id'";
        } elseif ($action == "ignore") {
            $sql = "DELETE FROM `friend_requests` WHERE `sender` = '$user_id' AND `receiver` = '$my_id'";
        } else {
            $sql = "DELETE FROM `friend_requests` WHERE (`sender` = '$my_id' AND `receiver` = '$user_id') OR (`sender` = '$user_id' AND `receiver` = '$my_id')";
        }
        try {
            $this->run_query(NULL, $sql);
            $this->profile_redirect();
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to make users friends
    function make_friends($my_id, $user_id)
    {
        $this->my_id = $my_id;
        $this->user_id = $user_id;

        try {
            $sql = "DELETE FROM `friend_requests` WHERE (`sender` = '$my_id' AND `receiver` = '$user_id') OR (`sender` = '$user_id' AND `receiver` = '$my_id')";
            $result = $this->run_query(NULL, $sql);
            if ($result) {
                $sql = "INSERT INTO `friends`(`user_one`, `user_two`) VALUES('$my_id', '$user_id')";
                $this->run_query(NULL, $sql);
            }
            $this->profile_redirect();
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to delete friends
    function delete_friends($my_id, $user_id)
    {
        $this->my_id = $my_id;
        $this->user_id = $user_id;

        try {
            $sql = "DELETE FROM `friends` WHERE (`user_one` = '$my_id' AND `user_two` = '$user_id') OR (`user_one` = '$user_id' AND `user_two` = '$my_id')";
            $this->run_query(NULL, $sql);
            $this->profile_redirect();
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to get friend request notifications
    function request_notification($my_id, $return_data = false)
    {
        if (!$this->id_validation([$my_id])) return false;
        try {
            // Construct SQL query to get friend requests
            $sql = "SELECT `sender`, `name`, users.id as `u_id` FROM `friend_requests` JOIN `users` ON friend_requests.sender = users.id WHERE `receiver` = '$my_id'";
            $result = $this->conn->query($sql);

            // Return data if requested
            if ($return_data) {
                return $result->fetchAll(PDO::FETCH_OBJ);
            }
            return $result->rowCount(); // Return number of friend requests
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }

    // Method to get all friends of a user
    function get_all_friends($my_id, $return_data = false)
    {
        if (!$this->id_validation([$my_id])) return false;

        try {
            // Construct SQL query to get all friends
            $sql = "SELECT * FROM `friends` WHERE `user_one` = '$my_id' OR user_two = '$my_id'";
            $result = $this->conn->query($sql);

            // Return data if requested
            if ($return_data) {
                $ids = [];
                $data = $result->fetchAll(PDO::FETCH_OBJ);
                if (count($data) === 0) return [];
                foreach ($data as $row) {
                    if ($row->user_one == $my_id) {
                        $ids[] = $row->user_two;
                        continue;
                    }
                    $ids[] = $row->user_one;
                }

                $sql = "SELECT `id`, `name` FROM `users` WHERE `id` IN (" . implode(',', array_map('intval', $ids)) . ")";
                return $this->conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
            }
            return $result->rowCount(); // Return number of friends
        } catch (PDOException $e) {
            $e->getMessage();
            exit;
        }
    }
}

Step 5: “init.php” Initialize Session and Autoload Classes

<?php
session_start();
session_regenerate_id(true);

// Autoloading Classes
spl_autoload_register(function ($class_name) {
    $path = __DIR__ . "/classes/";
    $theClass = "{$path}{$class_name}.php";
    if (file_exists($theClass)) return require_once $theClass;
    exit("Error: The \"{$class_name}\" class not found in {$path} || Or check your spelling.");
});

Step 6: Implement User Registration, Login and Logout

1. register.php: Handles user registration and displays a registration form.

<?php
require_once __DIR__ . "/init.php";

$result = NULL;

// Redirect if user is already logged in
if (isset($_SESSION['user_id'])) {
    header('Location: home.php');
    exit;
} else if (isset($_POST['email']) && isset($_POST['name']) && isset($_POST['password'])) {
    // Attempt registration
    $User = new User();
    $result = $User->register($_POST['name'], $_POST['email'], $_POST['password']);
}

// Function to retrieve old input values
function old_val($field_name)
{
    global $result;
    if (isset($result["ok"]) && $result["ok"]) return "";
    if (isset($_POST[$field_name])) return htmlspecialchars($_POST[$field_name]);
    return "";
}
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Register</title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>
    <div class="container form">
        <h1>Register</h1>
        <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST" novalidate>
            <label for="name">Name: <span class="err-msg name"></span></label>
            <input class="form-input" type="text" name="name" id="name" placeholder="Your name" value="<?php echo old_val("name"); ?>">

            <label for="email">Email: <span class="err-msg email"></span></label>
            <input class="form-input" type="email" name="email" id="email" placeholder="Your email" value="<?php echo old_val("email"); ?>">

            <label for="pass">Password: <span class="err-msg password"></span></label>
            <input class="form-input" type="password" name="password" id="pass" placeholder="Password" value="<?php echo old_val("password"); ?>">
            
            <?php if (isset($result['ok']) && isset($result['message']) && $result['ok'] === 1) : ?>
                <!-- Display success message -->
                <p class="s-msg">✔️ <?php echo $result['message']; ?> You may <a href="./login.php">login</a> now.</p>
            <?php endif; ?>

            <input class="button" type="submit" value="Login">
        </form>
        
        <!-- Link to login page -->
        <p class="link"><a href="./login.php">Login</a></p>
    </div>

    <?php if (isset($result["field_error"])) : ?>
        <script>
            // Display field validation errors
            let spanItem;
            let item;
            const errs = <?php echo json_encode($result["field_error"]); ?>;
            for (const property in errs) {
                spanItem = document.querySelector(`.err-msg.${property}`);
                item = document.querySelector(`[name="${property}"]`);
                item.classList.add('with-error');
                spanItem.innerText = errs[property];
            }
        </script>
    <?php endif; ?>
</body>

</html>
Registration form for a new user

2. login.php: Handles user login and displays a login form. It includes server-side validation and displays error messages if any fields fail validation.

<?php
// Include initialization script
require_once __DIR__ . "/init.php";

$result = NULL;

// Redirect if user is already logged in
if (isset($_SESSION['user_id'])) {
    header('Location: home.php');
    exit;
} elseif (isset($_POST['email']) && isset($_POST['password'])) {
    // Attempt login
    $User = new User();
    $result = $User->login($_POST['email'], $_POST['password']);
}

// Function to retrieve old input values
function old_val($field_name)
{
    if (isset($_POST[$field_name])) return htmlspecialchars($_POST[$field_name]);
    return "";
}
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>
    <div class="container form">
        <h1>Login</h1>
        <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST" novalidate>
            <label for="email">Email: <span class="err-msg email"></span></label>
            <input class="form-input" type="email" name="email" id="email" placeholder="Your email" value="<?php echo old_val("email"); ?>">
            <label for="pass">Password: <span class="err-msg password"></span></label>
            <input class="form-input" type="password" name="password" id="pass" placeholder="Password" value="<?php echo old_val("password"); ?>">
            <input class="button" type="submit" value="Login">
        </form>
        <!-- Link to registration page -->
        <p class="link"><a href="./register.php">Register</a></p>
    </div>

    <?php if (isset($result["field_error"])) : ?>
        <script>
            // Display field validation errors
            let spanItem;
            let item;
            const errs = <?php echo json_encode($result["field_error"]); ?>;
            for (const property in errs) {
                spanItem = document.querySelector(`.err-msg.${property}`);
                item = document.querySelector(`[name="${property}"]`);
                item.classList.add('with-error');
                spanItem.innerText = errs[property];
            }
        </script>
    <?php endif; ?>

</body>

</html>
PHP friend request system login form

3. logout.php: For user logout.

<?php
// Initialize the session.
// If you are using session_name("something"), don't forget it now!
session_start();

// Unset all of the session variables.
$_SESSION = array();

// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(
        session_name(),
        '',
        time() - 42000,
        $params["path"],
        $params["domain"],
        $params["secure"],
        $params["httponly"]
    );
}

// Finally, destroy the session.
session_destroy();
header("Location: login.php");
exit;

Step 7: Performs all Friend Request Actions

The actions.php handles various friend-related actions, such as sending friend requests, accepting friend requests, canceling friend requests, ignoring friend requests, and unfriending users.

<?php
// Include initialization script
require_once __DIR__ . "/init.php";

// Define valid actions
$actions = ["send", "unfriend", "cancel", "ignore", "accept"];

// Function to redirect user to home page
function redirect_to_home()
{
    header('Location: home.php');
    exit;
}

// Redirect if any required parameters are missing or invalid
if (
    !isset($_SESSION['user_id']) ||
    !isset($_GET["id"]) ||
    !isset($_GET["action"]) ||
    !in_array($_GET["action"], $actions) ||
    !filter_var($_GET["id"], FILTER_VALIDATE_INT) ||
    $_GET["id"] == $_SESSION['user_id']
) {
    redirect_to_home();
}

$action = $_GET["action"];

$User = new User();

// Find the current user and the target user
$the_user = $User->find_by_id($_SESSION['user_id']);
$x_user = $User->find_by_id($_GET['id']);

// Redirect if either user is not found
if (!$the_user || !$x_user) {
    redirect_to_home();
}

$my_id = $the_user->id;
$user_id = $x_user->id;

$Friend = new Friend();

// Handle different actions based on the requested action
if (
    $action === $actions[0] &&
    !($Friend->is_already_friends($my_id, $user_id) || $Friend->is_request_already_sent($my_id, $user_id))
) {
    // Send friend request
    $Friend->pending_friends($my_id, $user_id);
} elseif (
    in_array($action, [$actions[2], $actions[3]]) &&
    $Friend->is_request_already_sent($my_id, $user_id)
) {
    // Cancel or ignore friend request
    $Friend->cancel_or_ignore_friend_request($my_id, $user_id, $action);
} elseif (
    $action === $actions[4] &&
    !$Friend->is_already_friends($my_id, $user_id) &&
    $Friend->is_request_already_sent($my_id, $user_id)
) {
    // Accept friend request
    $Friend->make_friends($my_id, $user_id);
} elseif (
    $action === $actions[1] &&
    $Friend->is_already_friends($my_id, $user_id)
) {
    // Unfriend
    $Friend->delete_friends($my_id, $user_id);
} else {
    // Redirect if action is not recognized
    redirect_to_home();
}

Step 8: Create Pages for Logged in Users

1. nav.php: A component that contains dynamic navigation links.

<?php
function the_nav(int $notification = 0, int $total_friends = 0, $page = null)
{
    $n_badge = $notification ? '<span class="badge active">' . $notification . '</span>' : '<span class="badge">' . $notification . '</span>';
    $f_badge = '<span class="badge">' . $total_friends . '</span>';
?>
    <ul class="p_list d-flex">
        <li><?php echo ($page == "home") ? '<span>Home</span>' : '<a href="./home.php" class="active">Home</a>'; ?></li>

        <li><?php echo ($page == "info") ? "<span>Notification $n_badge</span>" : '<a href="./notifications.php">Notification ' . $n_badge . '</a>'; ?></li>

        <li><?php echo ($page == "frnd") ? "<span>Friends $f_badge</span>" : '<a href="./friends.php" class="active">Friends ' . $f_badge . '</a>'; ?></li>
        <li><a href="./logout.php">Logout</a></li>
    </ul>
<?php } ?>

2. home.php: home page of the logged-in user.

<?php
require_once __DIR__ . "/init.php";
if (!isset($_SESSION['user_id'])) {
    header('Location: logout.php');
    exit;
}
$User = new User();
$the_user = $User->find_by_id($_SESSION['user_id']);
if (!$the_user) {
    header('Location: logout.php');
    exit;
}
require_once __DIR__ . "/nav.php";
$all_users = $User->find_all_except($the_user->id);

$Friend = new Friend();
$notification = $Friend->request_notification($the_user->id);
$total_friends = $Friend->get_all_friends($the_user->id);
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>

    <div class="container profile">
        <div class="profile">
            <div class="p_user d-flex">
                <img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $the_user->id; ?>" alt="<?php echo $the_user->name; ?>">
                <h2><?php echo $the_user->name; ?></h2>
                <?php the_nav($notification, $total_friends); ?>
            </div>
        </div>
        <?php if ($all_users && count($all_users)) : ?>
            <h2 class="p-title">👥 All Users</h2>
            <div class="all-users">
                <ul class="user-list d-flex">
                    <?php foreach ($all_users as $user) : ?>
                        <li><a href="./profile.php?id=<?php echo $user->id; ?>"><img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $user->id; ?>" alt=""><span><?php echo $user->name; ?></span></a></li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php endif; ?>
    </div>
</body>

</html>
home page for logged in users

3. friends.php: Friends list of the logged-in user.

<?php
require_once __DIR__ . "/init.php";
if (!isset($_SESSION['user_id'])) {
    header('Location: logout.php');
    exit;
}
$User = new User();
$the_user = $User->find_by_id($_SESSION['user_id']);
if (!$the_user) {
    header('Location: logout.php');
    exit;
}
require_once __DIR__ . "/nav.php";
$all_users = $User->find_all_except($the_user->id);

$Friend = new Friend();
$notification = $Friend->request_notification($the_user->id);
$all_firends = $Friend->get_all_friends($the_user->id, true);
$total_friends = count($all_firends);
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Friend List</title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>

    <div class="container profile">
        <div class="profile">
            <div class="p_user d-flex">
                <img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $the_user->id; ?>" alt="<?php echo $the_user->name; ?>">
                <h2><?php echo $the_user->name; ?></h2>
                <?php the_nav($notification, $total_friends, "frnd"); ?>
            </div>
        </div>
        <?php if ($all_firends && count($all_firends)) : ?>
            <h2 class="p-title">🧑‍🤝‍🧑 Your Friends </h2>
            <div class="all-users">
                <ul class="user-list d-flex">
                    <?php foreach ($all_firends as $user) : ?>
                        <li><a href="./profile.php?id=<?php echo $user->id; ?>"><img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $user->id; ?>" alt=""><span><?php echo $user->name; ?></span></a></li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php else :
            echo '<h2 class="p-title">You have no friends.</h2>';
        endif; ?>
    </div>
</body>

</html>
friends page

4. profile.php – logged-in user can see other users’ profiles and send them friend requests.

<?php
require_once __DIR__ . "/init.php";
if (!isset($_SESSION['user_id'])) {
    header('Location: logout.php');
    exit;
}
$User = new User();
$the_user = $User->find_by_id($_SESSION['user_id']);
if (!$the_user) {
    header('Location: logout.php');
    exit;
}
if (!isset($_GET['id']) || $_GET['id'] === $the_user->id) {
    header('Location: home.php');
    exit;
}
$x_user = $User->find_by_id($_GET['id']);
if (!$x_user) {
    header('Location: home.php');
    exit;
}
require_once __DIR__ . "/nav.php";

$Friend = new Friend();

$notification = $Friend->request_notification($the_user->id);
$total_friends = $Friend->get_all_friends($the_user->id);

$req_receiver = $Friend->am_i_the_req("receiver", $the_user->id, $x_user->id);
$req_sender = $Friend->am_i_the_req("sender", $the_user->id, $x_user->id);
$already_friends = $Friend->is_already_friends($the_user->id, $x_user->id);
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>

    <div class="container profile">
        <div class="profile">
            <div class="p_user d-flex">
                <img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $x_user->id; ?>" alt="<?php echo $the_user->name; ?>">
                <h2><?php echo $x_user->name; ?></h2>
                <?php the_nav($notification, $total_friends); ?>
            </div>
        </div>
        <div class="actions">
            <?php
            $id = $x_user->id;
            if ($already_friends) {
                echo '<a href="./actions.php?id=' . $id . '&action=unfriend" class="btn btn-2">Unfriend</a>';
            } elseif ($req_sender) {
                echo '<a href="./actions.php?id=' . $id . '&action=cancel" class="btn btn-2">Cancel Request</a>';
            } elseif ($req_receiver) {
                echo '<a href="./actions.php?id=' . $id . '&action=ignore" class="btn btn-2">Ignore</a> &nbsp;<a href="./actions.php?id=' . $id . '&action=accept" class="btn btn-1">Accept</a>';
            } else {
                echo '<a href="./actions.php?id=' . $id . '&action=send" class="btn btn-1">Send Request</a>';
            }
            ?>
        </div>
    </div>
</body>

</html>
user profile page send friend request

5. notification.php – Notifications for friend-request.

<?php
require_once __DIR__ . "/init.php";
if (!isset($_SESSION['user_id'])) {
    header('Location: logout.php');
    exit;
}
$User = new User();
$the_user = $User->find_by_id($_SESSION['user_id']);
if (!$the_user) {
    header('Location: logout.php');
    exit;
}
require_once __DIR__ . "/nav.php";
$all_users = $User->find_all_except($the_user->id);

$Friend = new Friend();
$req_senders = $Friend->request_notification($the_user->id, true);
$total_friends = $Friend->get_all_friends($the_user->id);
$req_num = $req_senders ? count($req_senders) : 0;
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?php echo $req_num . ' Friend', (in_array($req_num, [0, 1])) ? ' Request' : ' Requests'; ?></title>
    <link rel="stylesheet" href="./assets/style.css">
</head>

<body>

    <div class="container profile">
        <div class="profile">
            <div class="p_user d-flex">
                <img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $the_user->id; ?>" alt="<?php echo $the_user->name; ?>">
                <h2><?php echo $the_user->name; ?></h2>
                <?php the_nav($req_num, $total_friends, "info"); ?>
            </div>
        </div>
        <?php if ($all_users && count($all_users)) : ?>
            <h2 class="p-title">You have <?php echo $req_num . ' Friend ', (in_array($req_num, [0, 1])) ? 'Request' : 'Requests'; ?></h2>
            <div class="all-users">
                <ul class="user-list d-flex">
                    <?php foreach ($req_senders as $user) : ?>
                        <li><a href="./profile.php?id=<?php echo $user->u_id; ?>"><img src="https://api.dicebear.com/6.x/bottts/png?seed=<?php echo $user->u_id; ?>" alt=""><span><?php echo $user->name; ?></span></a></li>
                    <?php endforeach; ?>
                </ul>
            </div>
        <?php endif; ?>
    </div>
</body>

</html>
friend request notification page

Step 9: Test this PHP Friend Request System

Open http://localhost/php-friend-request-system/register.php on your browser and test this application.

Download the Source Code:

Leave a Reply

Your email address will not be published. Required fields are marked *

We use cookies to ensure that we give you the best experience on our website. Privacy Policy