Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Saturday, 16 August 2025

Free PHP Project on Beauty Parlor Management System with MySQL

Free PHP Project on Beauty Parlor Management System with MySQL

Looking for a comprehensive, free PHP project to enhance your PHP web development skills or complete your final year project? This Beauty Parlor Management System in PHP MySQL is the perfect free educational project! This robust online web application empowers beauty salons to manage appointments, customers, services, and finances efficiently. Built with modern PHP MySQL project principles, it's a practical learning tool and a ready-to-use solution.

Powerful Admin Module: Complete Salon Control


  • Dashboard & Analytics: Monitor real-time stats (customers, appointments, sales) with interactive Chart.js visuals. Track performance for today, yesterday, last 7 days, and overall.

  • Appointment Management: View, filter, and search all bookings. Accept, reject, complete, or cancel appointments instantly via AJAX. Smart conflict prevention avoids double-booking.

  • Service Management: Full CRUD operations for services. Set dynamic pricing, track durations, and analyze popularity/booking frequency.

  • Customer Management: Maintain detailed client profiles with service history. Track loyalty via visit frequency and spending patterns.

  • Invoice Management: Automatically generate professional PDF invoices for completed bookings. Track payment status and generate financial reports.

  • Content Management: Easily manage About Us, Contact Us, and SEO-optimized pages using the integrated SUMMERNOTE WYSIWYG editor.

User-Friendly Client Portal


  • Account Management: Secure registration with email validation. Update profiles and manage passwords safely.

  • Appointment Booking: Intuitive step-by-step booking. Browse services, check real-time availability via the calendar, select slots, and get instant confirmation.

  • Personal Dashboard: View past/upcoming appointment history with real-time status updates. Book favorites quickly and access profile tools.

  • Invoice Access: View, download digital invoices, track payment history, and monitor personal spending.





Modern Technology Stack


  • Backend: PHP 8.0+ (Performance & Security), MySQL 8.0+ (Relational Database), PDO (Secure Database Access), Robust Session Management.

  • Frontend: HTML5 (Semantic Markup), CSS3 (Styling & Animations), Bootstrap 5 (Responsive Design), JavaScript ES6+ & jQuery 3.6+ (Interactivity & AJAX), Chart.js (Analytics Dashboards).

Why Choose This Project?


This Beauty Parlor Management System in PHP MySQL is more than software; it's a complete free educational project designed for learning and real-world application. Students gain hands-on experience in full-stack PHP web development, database design, and user experience principles – making it an ideal final year project. Salon owners get a free, powerful online web application to streamline operations, improve customer service, and boost revenue.

How to Set Up and Demo of Beauty Salon Management System





Tuesday, 28 January 2025

Employee Leave Management System in PHP using MySQL

Employee Leave Management System in PHP using MySQL


Introduction


An Employee Leave Management System is a powerful tool that simplifies the leave application and management process within an organization. It eliminates the need for manual tracking, paperwork, and inefficiencies by providing a digital platform for employees to apply for leave and administrators to manage requests seamlessly. This system ensures transparency, reduces administrative overhead, and improves the overall experience for both employees and management.





Features of the Employee Leave Management System


  1. Admin Dashboard: Provides an overview of total employees, departments, leave types, and leave statistics such as pending, approved, and rejected leave applications.
  2. Department Management: Add, edit, and manage departments with active/inactive status.
  3. Employee Management: Add, update, and manage employee details, including activation or deactivation of employee accounts.
  4. Leave Type Management: Define leave types such as casual leave, sick leave, and maternity leave with configurable allowances.
  5. Leave Application Processing: Admins can view, approve, reject, and add remarks to employee leave applications.
  6. Employee Dashboard: Allows employees to track their leave balance, view leave history, and stay updated on the status of their applications.
  7. Notifications: Real-time updates for leave application status changes and important announcements.
  8. Leave Balance Management: Tracks leave entitlements and deductions for each employee.
  9. Secure Login System: Role-based access for admins and employees with password encryption.
  10. Responsive Design: Fully optimized for use on desktops, tablets, and mobile devices.



Technologies Used


This Employee Leave Management System is built using the following web technologies:

  • Backend: PHP 8 for server-side scripting and MySQL for database management.
  • Frontend: HTML, CSS, and JavaScript for creating a responsive and user-friendly interface.
  • Frameworks/Libraries:
    • Bootstrap 5 for responsive design and styling.
    • jQuery for dynamic interactions and AJAX functionality.
    • CKEditor for rich text editing in leave descriptions.
  • Security: Password encryption using PHP's password hashing functions and secure session management.



Why Use This System?


  • Efficiency: Automates the entire leave management process, reducing manual errors and saving time.
  • Transparency: Employees can track their leave status in real-time, fostering trust and accountability.
  • Customization: Flexible leave types, allowances, and status updates to suit any organization's policies.
  • Cost-Effective: Minimizes administrative costs associated with traditional leave management methods.
  • Data Security: Ensures sensitive employee and leave data is securely stored and accessed.



Benefits of the System


  1. Simplified Leave Application: Employees can easily apply for leave without the need for paperwork or manual follow-ups.
  2. Better Decision-Making: Administrators have access to leave statistics and employee availability, making resource planning easier.
  3. Improved Productivity: With streamlined processes, both employees and administrators can focus on their core responsibilities.
  4. Scalability: The system can grow with the organization, accommodating more employees and leave types as needed.
  5. Compliance: Helps organizations adhere to labor laws by maintaining accurate leave records.





Database Structure


Below is a simplified structure of the database used in the Employee Leave Management System:

  • elms_admin:
    • admin_id (Primary Key)
    • admin_user_name
    • admin_password
  • elms_department:
    • department_id (Primary Key)
    • department_name
    • added_on
    • updated_on
  • elms_leave_type:
    • leave_type_id (Primary Key)
    • leave_type_name
    • added_on
    • updated_on
  • elms_employee:
    • employee_id (Primary Key)
    • employee_unique_code
    • employee_first_name
    • employee_last_name
    • employee_email
    • employee_password
    • employee_gender
    • employee_birthdate
    • employee_department (Foreign Key)
    • employee_address
    • employee_city
    • employee_country
    • employee_mobile_number
    • employee_status
  • elms_leave:
    • leave_id (Primary Key)
    • employee_id (Foreign Key)
    • leave_type (Foreign Key)
    • leave_start_date
    • leave_end_date
    • leave_description
    • leave_admin_remark
    • leave_status (Pending, Admin Read, Approved, Rejected)
    • leave_apply_date
    • leave_admin_remark_date



Download the Source Code


You can download the complete source code of this Employee Leave Management System from the link below:




Conclusion


The Employee Leave Management System is a practical and efficient solution for organizations of all sizes. It simplifies leave management, ensures transparency, and saves time for both employees and administrators. By implementing this system, organizations can enhance productivity, ensure compliance, and create a better work environment. Start using the Employee Leave Management System today and take a step towards modernizing your workforce management!

Friday, 6 September 2024

PHP MySQL Point of Sale (POS) System with Full Source Code

PHP MySQL Point of Sale (POS) System with Full Source Code

The PHP MySQL Point of Sale (POS) System is a powerful, flexible, and easy-to-use application designed to meet the needs of small to medium-sized restaurants, cafes, and retail stores. This system helps streamline operations by providing a comprehensive platform to manage orders, users, inventory, and more. Built using PHP and MySQL, this POS system is an ideal solution for businesses looking for a customizable and scalable system with full source code available.

Whether you’re running a restaurant or a cafe, the system is designed to optimize the point-of-sale experience, offering seamless order processing and user management, along with detailed analytics to help business owners track performance.

Key Features of the PHP MySQL POS System


1. Installation of POS System


The system comes with a straightforward installation process. With just a few clicks, users can get the system up and running on their server. This user-friendly installation ensures minimal setup time.

2. Auto Create Database


During the installation process, the system automatically generates the necessary database tables and structure. This eliminates the need for manual database creation, making the setup process even smoother.

3. Create Admin User


A secure feature that allows the creation of an admin user during setup. The admin has full control over the system, from managing orders to overseeing user roles and system settings.

4. Set Up Restaurant or Cafe POS System


Whether you're running a restaurant or cafe, the system is tailored to your specific needs. The setup process lets you configure items, categories, and pricing, making it easy to get started with your business operations.





5. User Management


Admins can manage user roles, such as cashier or manager, with varying levels of access. This feature ensures that only authorized personnel have access to sensitive sections of the system.

6. Item Category Management


Keep your inventory organized by creating and managing categories for items, such as food, beverages, or merchandise. This makes it easier to track stock and streamline the ordering process.

7. Item Management


Manage items in your inventory with ease. You can add, update, and remove items, set pricing, and even attach them to specific categories for better organization.

8. User Profile


Every user has their own profile where they can update personal information and view order history. This adds a personalized experience for employees or customers interacting with the system.

9. Change Password


Users have the ability to securely change their passwords through the system’s interface. This enhances security by allowing users to update credentials regularly.

10. Create Order


The system enables efficient order creation, allowing users to quickly input customer orders and add items to the cart. The 'Create Order' feature ensures smooth transaction processing.

11. Order Management


The system allows you to view, manage, and update orders as needed. Admins can track completed orders, pending orders, and adjust details where necessary, ensuring efficient order handling.

12. Analytics


Gain insights into business performance through detailed analytics. Track daily sales, total revenue, and customer order trends. This feature helps you make data-driven decisions to grow your business.

This PHP MySQL POS System is a full-fledged solution that covers all aspects of order management, inventory control, and user administration. With its open-source code, you can further customize the system to meet your specific business needs.

Video Demo of PHP MySQL POS System








Tuesday, 9 January 2024

Mastering User Registration and Email Verification in PHP with JWT Tokens: A Comprehensive Guide


In the ever-evolving landscape of web development, ensuring a secure and streamlined user registration process is paramount. One powerful way to enhance the security of your PHP-based applications is by implementing user registration and email verification using JSON Web Tokens (JWT). In this guide, we'll walk you through the process step by step, empowering you to bolster the authentication mechanisms of your PHP projects.


Mastering User Registration and Email Verification in PHP with JWT Tokens: A Comprehensive Guide


Understanding the Basics


What is JWT?


JSON Web Tokens (JWT) provide a secure and compact way to transmit information between parties. In the context of user authentication, JWTs can be used to securely store user data and ensure that information is not tampered with during transmission.

Why PHP?


PHP remains a popular server-side scripting language, particularly for web development. Its versatility, ease of use, and extensive community support make it an excellent choice for implementing robust authentication systems.

Step-by-Step Guide


1. Setting Up Your PHP Environment


Ensure that your PHP environment is configured correctly. This includes setting up a database to store user information securely.


CREATE TABLE `user` (
  `user_id` int NOT NULL AUTO_INCREMENT,
  `user_email` varchar(70) DEFAULT NULL,
  `user_password` varchar(45) DEFAULT NULL,
  `user_name` varchar(45) DEFAULT NULL,
  `email_verification_status` enum('Not Verified','Verified') DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `user` VALUES (1,'johnsmith@gmail.com','password','John Smith','Verified'),(16,'peterparker@mailinator.com','password','Peter Parker','Verified'),(17,'donna@mailinator.com','password','Donna Hubber','Verified'),(18,'mike@mailinator.com','password','Mike','Verified');


2. Integrating JWT Library


Choose a reliable JWT library for PHP, such as Firebase JWT. Integrate it into your project to start creating and validating JWTs.


composer require firebase/php-jwt


3. User Registration


Implement a user registration system that securely stores user data in your database. Hash passwords using strong encryption algorithms to enhance security.

4. Generating JWTs


Upon successful registration, generate a JWT containing relevant user information. This token will serve as a secure means of verifying the user's identity in subsequent requests.

5. Email Verification


Send a verification email containing a link with a JWT to the user's registered email address. This link will confirm the user's identity and activate their account.

6. Token Validation


Implement a mechanism to validate JWTs in subsequent user requests. This ensures that only authenticated users can access protected resources.

Best Practices and Security Measures


1. Use HTTPS


Ensure your application is served over HTTPS to encrypt data transmitted between the user and the server, preventing man-in-the-middle attacks.

2. Token Expiry


Set a reasonable expiration time for your JWTs to mitigate the risk of unauthorized access.

3. Secure Database Storage


Employ secure practices for storing user data in the database, such as hashing and salting passwords.

4. Rate Limiting


Implement rate limiting to prevent brute-force attacks on the authentication system.

Conclusion


By following this comprehensive guide, you'll be well-equipped to implement a robust user registration and email verification system using PHP and JWT. Enhance the security of your applications, protect user data, and provide a seamless experience for your users. Stay ahead in the world of web development by mastering the art of authentication with PHP and JWT tokens.





Source Code


register.php

<?php 

//register.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$error = '';

$message = '';

if(isset($_POST['register']))
{
	$connect = new PDO("mysql:host=localhost; dbname=testing", "root", "password");

	if(empty($_POST['name']))
	{
		$error = 'Please Enter Name Details';
	}
	else if(empty($_POST['email']))
	{
		$error = 'Please Enter Email Details';
	}
	else if(empty($_POST['password']))
	{
		$error = 'Please Enter Password Details';
	}
	else
	{
		$query = "SELECT user_id FROM user WHERE user_email = ?";
		$statement = $connect->prepare($query);
		$statement->execute([$_POST["email"]]);
		if($statement->rowCount() > 0)
		{
			$error = 'Email Alaready Exists';
		}
		else
		{
			$data = array(
				':user_email'		=>	trim($_POST['email']),
				':user_password'	=>	trim($_POST['password']),
				':user_name'		=>	trim($_POST['name']),
				':email_verification_status'	=>	'Not Verified'
			);

			$insertQuery = "INSERT INTO user (user_email, user_password, user_name, email_verification_status) VALUES (:user_email, :user_password, :user_name, :email_verification_status)";
			$statement = $connect->prepare($insertQuery);
			if($statement->execute($data))
			{
				$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

				$payload = array(
					'email'		=>	trim($_POST['email'])
				);

				$token = JWT::encode($payload, $key, 'HS256');

				$verificationLink = 'http://localhost/tutorial/php-jwt-login/verify.php?token='.$token;

				$mail = new PHPMailer(true);
				$mail->isSMTP();
				$mail->Host = 'smtp.gmail.com';
				$mail->SMTPAuth = true;
				$mail->Username = 'your gmail address';
				$mail->Password = 'xxx'; //Here you have to define your gmail password
				$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
				$mail->Port = 587;
				$mail->setFrom('sender@email.com', 'sender@email.com');
				$mail->addAddress(trim($_POST['email']), trim($_POST['name']));
				$mail->isHTML(true);
				$mail->Subject = 'Verify Your Email Address';
				$mail->Body = '
				<p>Hi,</p>
			    <p>Thank you for registering with us! To complete your registration and activate your account, please click on the following link:</p>
			    <p><a href="'.$verificationLink.'">'.$verificationLink.'</a></p>
			    <p>Thank you,<br />Webslesson.info</p>
				';
				$mail->send();
				$message = 'Verification eMail has been send! Registration Complete!';
			}
		}
	}
}

?>

<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>PHP Registration & Email Validation using JWT Token</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">PHP Registration & Email Validation using JWT Token</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4">
    				<?php

    				if($error !== '')
    				{
    					echo '<div class="alert alert-danger">'.$error.'</div>';
    				}

    				if($message !== '')
    				{
    					echo '<div class="alert alert-success">'.$message.'</div>';
    				}

    				?>
		    		<div class="card">
		    			<div class="card-header">Register</div>
		    			<div class="card-body">
		    				<form method="post">
		    					<div class="mb-3">
			    					<label>Name</label>
			    					<input type="text" name="name" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Email</label>
			    					<input type="email" name="email" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Password</label>
			    					<input type="password" name="password" class="form-control" />
			    				</div>
			    				<div class="text-center">
			    					<input type="submit" name="register" value="Register" class="btn btn-primary" />
			    				</div>
		    				</form>
		    			</div>
		    		</div>
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


verify.php

<?php

//verify.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

$token = '';
$payload = array();

if(isset($_GET['token']))
{
	$connect = new PDO("mysql:host=localhost; dbname=testing", "root", "password");
	$decoded = JWT::decode($_GET['token'], new Key($key, 'HS256'));
	$checkQuery = 'SELECT email_verification_status FROM user WHERE user_email = "'.$decoded->email.'"';
	$result = $connect->query($checkQuery);
	foreach($result as $row)
	{
		if($row['email_verification_status'] === 'Verified')
		{
			$payload = array(
				'msg'	=>	'Your Email Already Verified, You can login'
			);
		}
		else
		{
			$query = 'UPDATE user SET email_verification_status = "Verified" WHERE user_email = "'.$decoded->email.'"';
			$statement = $connect->prepare($query);
			$statement->execute();
			$payload = array(
				'msg'	=>	'Email Successfully verify, now you can login'
			);
		}
		$token = JWT::encode($payload, $key, 'HS256');
		header('location:index.php?token='.$token);
	}
}

?>


index.php

<?php

//index.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

$message = '';
$error = '';

if(isset($_GET['token']))
{
	$decoded = JWT::decode($_GET['token'], new Key($key, 'HS256'));
	$message = $decoded->msg;
}

if(isset($_POST["login"]))
{
	$connect = new PDO("mysql:host=localhost;dbname=testing", "root", "password");

	if(empty($_POST["email"])){
		$error = 'Please Enter Email Details';
	} else if(empty($_POST["password"])){
		$error = 'Please Enter Password Details';
	} else {
		$query = "SELECT * FROM user WHERE user_email = ?";
		$statement = $connect->prepare($query);
		$statement->execute([$_POST["email"]]);
		$data = $statement->fetch(PDO::FETCH_ASSOC);
		if($data){
			if($data['user_password'] ===  $_POST['password']){
				
				$token = JWT::encode(
					array(
						'iat'		=>	time(),
						'nbf'		=>	time(),
						'exp'		=>	time() + 3600,
						'data'	=> array(
							'user_id'	=>	$data['user_id'],
							'user_name'	=>	$data['user_name']
						)
					),
					$key,
					'HS256'
				);
				setcookie("token", $token, time() + 3600, "/", "", true, true);
				header('location:welcome.php');

			} else {
				$error = 'Wrong Password';
			}
		} else {
			$error = 'Wrong Email Address';
		}
	}
}

?>


<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login using JWT Token in PHP</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login using JWT Token in PHP</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4">
    				<?php

    				if($error !== '')
    				{
    					echo '<div class="alert alert-danger">'.$error.'</div>';
    				}

    				if($message !== '')
    				{
    					echo '<div class="alert alert-info">'.$message.'</div>';
    				}

    				?>
		    		<div class="card">
		    			<div class="card-header">Login</div>
		    			<div class="card-body">
		    				<form method="post">
		    					<div class="mb-3">
			    					<label>Email</label>
			    					<input type="email" name="email" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Password</label>
			    					<input type="password" name="password" class="form-control" />
			    				</div>
			    				<div class="text-center">
			    					<input type="submit" name="login" class="btn btn-primary" value="Login" />
			    				</div>
		    				</form>
		    			</div>
		    		</div>
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


welcome.php

<?php

//welcome.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

if(isset($_COOKIE['token'])){
	$decoded = JWT::decode($_COOKIE['token'], new Key($key, 'HS256'));
} else {
	header('location:index.php');
}

?>

<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login in PHP using JWT Token</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login in PHP using JWT Token</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4 text-center">
    				<h1>Welcome <b><?php echo $decoded->data->user_name; ?></b></h1>
    				<a href="logout.php">Logout</a>
    				
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


logout.php

<?php

//logout.php

setcookie("token", "", time() - 3600,  "/", "", true, true);

header('location:index.php');

?>


Saturday, 2 December 2023

Building a React.js CRUD Application with Vite, PHP API and MySQL

Building a React.js CRUD Application with Vite, PHP API, and MySQL


In this tutorial, we'll walk through the process of creating a full-stack CRUD (Create, Read, Update, Delete) application using React.js, Vite for the frontend, PHP for the backend, and MySQL as the database. This project will help you understand how to set up a modern development environment and integrate the different components seamlessly.

Prerequisites


Before getting started, make sure you have the following tools installed:

  • Node.js
  • npm (Node Package Manager)
  • PHP
  • Composer
  • MySQL

Steps for Create PHP React CRUD Application


  1. Installation
  2. Set Router for Fetch Data
  3. Create Fetch Data API
  4. Make Insert Data Component & Set Route
  5. Submit Form Data
  6. Set Router for Edit Data Component
  7. Make Update Data API
  8. Create Delete Data API




Step 1 - Installation


Here we have make CRUD Application by using React.js with PHP API. So first we want to download and install React.js on our local computer. So here we have use Vite tool and it is a front end tool which is used for building fast and optimized web application.

Now we want to download React Framework by using Vite. So first we have goes to command prompt and And here we have goes into directory from which we can run PHP application and for download and install React.js we have to run following command in terminal.


npm create vite@latest phpreactcrud


When you have run this command then it will create phpreactcrud directory and then after it will display JavaScript framework and from this list of framework we have to select React framework by pressing down key. And after selecting React and press enter then it has again ask for selecting JavaScript variant. So by pressing down key we have to select JavaScript and press enter.

After this, we have goes into phpreactcrud directory by run following command.


cd phpreactcrud


Inside your project directory, you'll need to install the project's dependencies using npm:


npm install


So after run this command it will start download React framework in phpreactcrud directory. Once download is complete, so we need to check React is properly install or not. So we have need to run following command.


npm run dev


When we have run this command then it will start React development server and provide us base url of our React Application. So from this url we can open React Application in the browser.

If React web page open in browser that means React is properly installed in our computer.

Directory Structure of React

Below you can find directory structure of React.js framework.


Directory Structure of React.js CRUD Application


Step 2 - Set Router for Fetch Data


This is second step for create PHP React.js CRUD application and under this step we have to set Router for Fetch Data. But before set Router for fetch data, first we have to install Bootstrap 5 library under this React CRUD Application.

So To use Bootstrap 5 in your React application, you need to install the Bootstrap package from npm. Bootstrap 5 comes with Sass, so you can take advantage of its customization features. Run the following command to install Bootstrap:


npm install bootstrap


So this command will download and install Bootstrap 5 library under this our React.js Application. Next we have to use Bootstrap library under this React CRUD Application.

So we have to open src/App.jsx file and for import the Bootstrap CSS at the top of the file:


import 'bootstrap/dist/css/bootstrap.min.css';


Next for display user data, we have to create Component/Userlist.jsx file and under this file, we want to import React, so we have to write following statement under this file.


import React from 'react';


So it will import React dependencies under this file. After this we have create React component for this Userlist by writing following code.

Component/Userlist.jsx

function Userlist(){
	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6"><b>User Data</b></div>
					<div className="col-md-6">

					</div>
				</div>
			</div>
			<div className="card-body">
				<table className="table table-bordered">
					<thead>
						<tr>
							<th>First Name</th>
							<th>Last Name</th>
							<th>Email</th>
							<th>Action</th>
						</tr>
					</thead>
					<tbody>
					
					</tbody>
				</table>
			</div>
		</div>
	);
}


And for export this component, we have to write following code at the end of this file. So after write this code we can import this component in other file also.


export default Userlist;


Next we have open App.jsx file and under this file we have to first import React router dom library. So we have goes to command prompt and run following command. This command will download and install React router dom library under this App.jsx file.


npm install react-router-dom


After installing this library we can able to import React router dom library component like BrowserRouter, Routes, Route, Link by writing following statement under App.jsx file.


import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';


BrowserRouter - Here BrowserRouter component is represents the router for your application, And it is the key component from react router dom, which provided routing functionality to react application.

Routes - Routes component is typically used to define collection of routes.

Route - Route component is used to define, individual route in your application.

Link - Link component is used for creating hyperlink, that navigate to different parts of your application.

Next we want to import Component/Userlist.jsx file under this App.jsx file. So we have to add following statement under App.jsx file.


import Userlist from './Component/Userlist';


After import React router dom library and Userlist component, in below code you can find how to define route for fetch data.

src/App.jsx

import { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import Userlist from './Component/Userlist';

function App() {
    return(
        <div className="container">
            <h1 className="mt-5 mb-5 text-center"><b>PHP React.js CRUD Application - <span className="text-primary">Create Delete Data API - 8</span></b></h1>
            <BrowserRouter>
                <Routes>
                    <Route path="/" element={<Userlist />} />
                </Routes>
            </BrowserRouter>
        </div>
    )
}

export default App



src/Component/Userlist.jsx

import React from 'react';

function Userlist(){

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6"><b>User Data</b></div>
					<div className="col-md-6">
						
					</div>
				</div>
			</div>
			<div className="card-body">
				<table className="table table-bordered">
					<thead>
						<tr>
							<th>First Name</th>
							<th>Last Name</th>
							<th>Email</th>
							<th>Action</th>
						</tr>
					</thead>
					<tbody>
					
					</tbody>
				</table>
			</div>
		</div>
	);
}

export default Userlist;




Step 3 - Create Fetch Data API


After set Router for Fetch Data, now we want to make PHP API for fetch data from MySQL table. But before this we have to write JavaScript under Component/Userlist.jsx file for send fetch data request to PHP API.

Source Code of Create Fetch Data API

src/Component/Userlist.jsx

import React, { useEffect, useState } from 'react';

function Userlist(){
	const [users, setUsers] = useState([]);

	useEffect(() => {
		const apiUrl = 'http://localhost/tutorial/phpreactcrud/api/action.php'; //This URL change according to path of your PHP Script

		fetch(apiUrl)
		.then((response) => response.json())
		.then((data) => {
			setUsers(data);
		});

	}, []);

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6"><b>User Data</b></div>
					<div className="col-md-6">
						
					</div>
				</div>
			</div>
			<div className="card-body">
				<table className="table table-bordered">
					<thead>
						<tr>
							<th>First Name</th>
							<th>Last Name</th>
							<th>Email</th>
							<th>Action</th>
						</tr>
					</thead>
					<tbody>
					{users.map((user, index) => (
						<tr key={index}>
							<td>{user.first_name}</td>
							<td>{user.last_name}</td>
							<td>{user.email}</td>
							<td>
								
							</td>
						</tr>
					))}
					</tbody>
				</table>
			</div>
		</div>
	);
}

export default Userlist;


1 - Import Statements:


import React, { useEffect, useState } from 'react';


  • The code imports the necessary functionalities from the react library.
  • useEffect is a hook used for side effects in functional components, and useState is a hook for managing state.

2 - Component Definition:


function Userlist(){


  • The functional component named Userlist is defined.

3 - State Initialization:


const [users, setUsers] = useState([]);


  • This line initializes a state variable users using the useState hook. The setUsers function is used to update the state.

4 - Data Fetching using useEffect:


useEffect(() => {
    const apiUrl = 'http://localhost/tutorial/phpreactcrud/api/action.php';

    fetch(apiUrl)
    .then((response) => response.json())
    .then((data) => {
        setUsers(data);
    });

}, []);


  • The useEffect hook is used to perform side effects in functional components. In this case, it fetches data from a specified API endpoint when the component mounts ([] as the dependency array means it runs once when the component mounts).
  • The data fetched is expected to be in JSON format, and it updates the users state with the received data.

5 - Rendering JSX:


return (
    <div className="card">
        {/* ... */}
    </div>
);


  • The return statement contains JSX code that represents the structure of the component.

6 - JSX Structure:

  • The component renders a Bootstrap-styled card with a header and body.
  • The body contains a table displaying user data with columns for "First Name," "Last Name," "Email," and an "Action" column.

7 - Mapping Through User Data:


{users.map((user, index) => (
    <tr key={index}>
        <td>{user.first_name}</td>
        <td>{user.last_name}</td>
        <td>{user.email}</td>
        <td>
            {/* Action content */}
        </td>
    </tr>
))}


  • The component maps through the users array and renders a table row (</tr>) for each user.
  • User details such as first name, last name, and email are displayed in the corresponding columns.

8 - Export Statement:


export default Userlist;


  • The Userlist component is exported as the default export of this module, making it available for use in other parts of the application.
api/action.php

<?php

header("Access-Control-Allow-Origin:* ");

header("Access-Control-Allow-Headers:* ");

header("Access-Control-Allow-Methods:* ");

$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");

$method = $_SERVER['REQUEST_METHOD']; //return GET, POST, PUT, DELETE

if($method === 'GET')
{
	//fetch all user

		$query = "SELECT * FROM sample_users ORDER BY id DESC";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data[] = $row;
		}

		echo json_encode($data);
	
}


?>


This PHP code is designed to handle HTTP requests, specifically for the GET method, and it interacts with a MySQL database to retrieve data. Let's break down the code:

1 - Cross-Origin Resource Sharing (CORS) Headers:


header("Access-Control-Allow-Origin:* ");
header("Access-Control-Allow-Headers:* ");
header("Access-Control-Allow-Methods:* ");


  • These lines set up CORS headers, allowing cross-origin requests from any origin (*). CORS headers are necessary for web applications hosted on one domain to make requests to a different domain.

2 - Database Connection:


$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");


  • It establishes a connection to a MySQL database named "testing" on the local server (127.0.0.1). The username is "root," and the password is "password." This connection is created using the PDO (PHP Data Objects) extension.

3 - Request Method Check:


$method = $_SERVER['REQUEST_METHOD'];


  • It retrieves the HTTP request method (GET, POST, PUT, DELETE) from the $_SERVER superglobal.

4 - Handling GET Requests:


if ($method === 'GET') {
    //fetch all user
    $query = "SELECT * FROM sample_users ORDER BY id DESC";
    $result = $connect->query($query, PDO::FETCH_ASSOC);
    
    $data = array();
    foreach ($result as $row) {
        $data[] = $row;
    }
    echo json_encode($data);
}


  • If the request method is GET, the code executes a SELECT query to retrieve all records from the "sample_users" table, ordering them by the "id" column in descending order.
  • The result of the query is fetched using the query method, and the data is extracted using a foreach loop.
  • The retrieved data is then encoded as JSON using json_encode and echoed back to the client.

This PHP code handles GET requests, connects to a MySQL database, retrieves all records from a specific table, and returns the data in JSON format with appropriate CORS headers to allow cross-origin requests.




Step 4 - Make Insert Data Component & Set Route


Once we have fetch data from MySQL database and display on web page under this React.js CRUD Application. Next We will create insert data component in which we will create Add user data form, and then after we will set router of that insert data component under this React.js PHP CRUD Application.

src/Component/Add.jsx

import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';

function Add(){

	let navigate = useNavigate();

	const [user, setUser] = useState({
		first_name : '',
		last_name : '',
		email : ''
	});

	const handleChange = (event) => {
		const { name, value } = event.target;

		setUser({
			...user,
			[name] : value
		});
	};

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6">Add User</div>
					<div className="col-md-6">
						<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<div className="row">
					<div className="col-md-4">&nbsp;</div>
					<div className="col-md-4">
						<form method="POST">
							<div className="mb-3">
								<label>First Name</label>
								<input type="text" name="first_name" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Last Name</label>
								<input type="text" name="last_name" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Email</label>
								<input type="email" name="email" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<input type="submit" className="btn btn-primary" value="Add" />
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
	);
}

export default Add;


This React.js code defines a functional component called Add that represents a form for adding a new user. It uses the useNavigate hook from react-router-dom to programmatically navigate between different views. Let's break down the code:

1 - Import Statements:


import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';


  • The code imports the necessary functionalities from the react library, including the useState hook.
  • It also imports Link and useNavigate from react-router-dom. Link is used to create navigation links, and useNavigate is a hook used for programmatic navigation.

2 - Component Definition:


function Add(){


  • The functional component named Add is defined.

3 - Navigation Setup:


let navigate = useNavigate();


  • The useNavigate hook is used to get the navigate function, which can be used to navigate between different views in a React application.

4 - State Initialization:


const [user, setUser] = useState({
    first_name : '',
    last_name : '',
    email : ''
});


  • This line initializes a state variable user using the useState hook. The state represents the user data with properties first_name, last_name, and email.

5 - Event Handler Function:


const handleChange = (event) => {
    const { name, value } = event.target;

    setUser({
        ...user,
        [name] : value
    });
};


  • The handleChange function is an event handler for input changes. It uses object destructuring to extract the name and value from the changed input element.
  • The setUser function is then used to update the user state by spreading the existing state and updating the property corresponding to the changed input.

6 - Rendering JSX:


return (
    <div className="card">
        {/* ... */}
    </div>
);


  • The return statement contains JSX code that represents the structure of the component.

7 - JSX Structure:

  • The component renders a Bootstrap-styled card with a header and body.
  • The body contains a form with input fields for "First Name," "Last Name," and "Email," along with a submit button labeled "Add."

8 - Navigation Link:


<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>


  • This is a Link component that creates a link to the root path ("/"). It's styled as a Bootstrap button and is labeled "View All."
  • Clicking on this link will navigate the user to the specified path.

9 - Form Input Fields:


<input type="text" name="first_name" className="form-control" onChange={handleChange} />
<input type="text" name="last_name" className="form-control" onChange={handleChange} />
<input type="email" name="email" className="form-control" onChange={handleChange} />


  • These input fields are controlled components, meaning their values are controlled by the state (user).
  • The onChange event is set to the handleChange function, ensuring that any changes to the input fields update the state.

10 - Submit Button:


<input type="submit" className="btn btn-primary" value="Add" />


  • This is a submit button for the form. It triggers the submission of the form data.

11 - Export Statement:


export default Add;


  • The Add component is exported as the default export of this module, making it available for use in other parts of the application.

This component provides a form for adding a new user. It captures input changes, updates the component state accordingly, and allows for the submission of the form data.

After creating this src/Component/Add.jsx file, now we want to import in src/App.jsx file.

src/App.jsx

import { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import Userlist from './Component/Userlist';
import Add from './Component/Add';

function App() {
    return(
        <div className="container">
            <h1 className="mt-5 mb-5 text-center"><b>PHP React.js CRUD Application - <span className="text-primary">Create Delete Data API - 8</span></b></h1>
            <BrowserRouter>
                <Routes>
                    <Route path="/" element={<Userlist />} />
                    <Route path="/add" element={<Add />} />
                </Routes>
            </BrowserRouter>
        </div>
    )
}

export default App



1 - Import Statements:


import Add from './Component/Add';


  • Component Add are imported from separate files.

2 - React Router Setup:


<BrowserRouter>
    <Routes>
        /* ... */
        <Route path="/add" element={<Add />} />
    </Routes>
</BrowserRouter>


  • The BrowserRouter component from react-router-dom is used to set up routing for the application.
  • Inside it, the Routes component defines different routes using the Route component. Two routes are defined:
    • The path /add renders the Add component.

So this way we can create Add user form component and import into App.jsx file.




Step 5 - Submit Form Data


Now you can move to How to submit form data by using React handle submit function and then after you will learn how to make PHP API for Insert Form data under this React CRUD Application.

src/Component/Add.jsx

import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';

function Add(){

	let navigate = useNavigate();

	const [user, setUser] = useState({
		first_name : '',
		last_name : '',
		email : ''
	});

	const handleChange = (event) => {
		const { name, value } = event.target;

		setUser({
			...user,
			[name] : value
		});
	};

	const handleSubmit = (event) => {

		event.preventDefault();

		fetch('http://localhost/tutorial/phpreactcrud/api/action.php', {
			method : 'POST',
			headers : {
				'Content-Type' : 'application/json'
			},
			body : JSON.stringify(user)
		})
		.then((response) => response.json())
		.then((data) => {
			navigate("/");
		})

	};

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6">Add User</div>
					<div className="col-md-6">
						<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<div className="row">
					<div className="col-md-4">&nbsp;</div>
					<div className="col-md-4">
						<form method="POST" onSubmit={handleSubmit}>
							<div className="mb-3">
								<label>First Name</label>
								<input type="text" name="first_name" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Last Name</label>
								<input type="text" name="last_name" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Email</label>
								<input type="email" name="email" className="form-control" onChange={handleChange} />
							</div>
							<div className="mb-3">
								<input type="submit" className="btn btn-primary" value="Add" />
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
	);
}

export default Add;


1 - Event Handler Function (handleSubmit):


const handleSubmit = (event) => {
    event.preventDefault();

    fetch('http://localhost/tutorial/phpreactcrud/api/action.php', {
        method : 'POST',
        headers : {
            'Content-Type' : 'application/json'
        },
        body : JSON.stringify(user)
    })
    .then((response) => response.json())
    .then((data) => {
        navigate("/");
    });
};


  • The handleSubmit function is an event handler for form submission. It prevents the default form submission behavior using event.preventDefault().
  • It then makes a POST request to the specified API endpoint ('http://localhost/tutorial/phpreactcrud/api/action.php') with the user data in JSON format.
  • Upon successful submission, it navigates the user back to the root path ("/") using the navigate function.

2 - Form onSubmit Event Handler:


<form method="POST" onSubmit={handleSubmit}>


  • The onSubmit attribute is set to the handleSubmit function.
  • This means that when the form is submitted (either by clicking a submit button or pressing Enter within a form field), the handleSubmit function will be called.
api/action.php

<?php

header("Access-Control-Allow-Origin:* ");

header("Access-Control-Allow-Headers:* ");

header("Access-Control-Allow-Methods:* ");

$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");

$method = $_SERVER['REQUEST_METHOD']; //return GET, POST, PUT, DELETE

if($method === 'GET')
{	
	//fetch all user

	$query = "SELECT * FROM sample_users ORDER BY id DESC";

	$result = $connect->query($query, PDO::FETCH_ASSOC);

	$data = array();

	foreach($result as $row)
	{
		$data[] = $row;
	}

	echo json_encode($data);
}

if($method === 'POST')
{
	$form_data = json_decode(file_get_contents('php://input'));

	$data = array(
		':first_name'		=>	$form_data->first_name,
		':last_name'		=>	$form_data->last_name,
		':email'			=>	$form_data->email
	);

	$query = "
	INSERT INTO sample_users (first_name, last_name, email) VALUES (:first_name, :last_name, :email);
	";

	$statement = $connect->prepare($query);

	$statement->execute($data);

	echo json_encode(["success" => "done"]);
}

?>


This PHP code is a simple server-side script that handles HTTP requests, specifically for the POST method. It interacts with a MySQL database to insert data submitted through a JSON-encoded payload.


if($method === 'POST') {
    // Process POST data

    $form_data = json_decode(file_get_contents('php://input'));

    $data = array(
        ':first_name'		=>	$form_data->first_name,
        ':last_name'		=>	$form_data->last_name,
        ':email'			=>	$form_data->email
    );

    $query = "
    INSERT INTO sample_users (first_name, last_name, email) VALUES (:first_name, :last_name, :email);
    ";

    $statement = $connect->prepare($query);

    $statement->execute($data);

    echo json_encode(["success" => "done"]);
}


  • If the request method is POST, the code proceeds to handle the incoming data.
  • It uses json_decode to parse the JSON data received from the client via the php://input stream.
  • The parsed data is then used to construct an associative array $data with keys corresponding to database columns.
  • A SQL query is prepared to insert the data into the "sample_users" table.
  • The query is executed using the prepared statement, and a success message is echoed back as a JSON response.

In summary, this PHP script checks for incoming POST requests, parses the JSON data, inserts it into a MySQL database, and responds with a JSON success message.




Step 6 - Set Router for Edit Data Component


Under this step, you can find how to create Edit component under this React Crud application and then after, we will set route for that edit component, under this React Application.

src/Component/Userlist.jsx

import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

function Userlist(){
	const [users, setUsers] = useState([]);

	useEffect(() => {
		const apiUrl = 'http://localhost/tutorial/phpreactcrud/api/action.php';

		fetch(apiUrl)
		.then((response) => response.json())
		.then((data) => {
			setUsers(data);
		});

	}, []);

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6"><b>User Data</b></div>
					<div className="col-md-6">
						<Link to="/add" className="btn btn-success btn-sm float-end">Add</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<table className="table table-bordered">
					<thead>
						<tr>
							<th>First Name</th>
							<th>Last Name</th>
							<th>Email</th>
							<th>Action</th>
						</tr>
					</thead>
					<tbody>
					{users.map((user, index) => (
						<tr key={index}>
							<td>{user.first_name}</td>
							<td>{user.last_name}</td>
							<td>{user.email}</td>
							<td>
								<Link to={`/edit/${user.id}`} className="btn btn-warning btn-sm">Edit</Link>
							</td>
						</tr>
					))}
					</tbody>
				</table>
			</div>
		</div>
	);
}

export default Userlist;


Here We have uses the Link component from react-router-dom to create a navigation link styled as a Bootstrap button. Clicking the link navigates the user to an "edit" route with a dynamic parameter, specifically the id property of a user object. This pattern is often used to implement edit functionality in React applications.

src/Component/Edit.jsx

import React, {useState, useEffect} from 'react';

import { Link, useNavigate, useParams } from 'react-router-dom';

function Edit(){

	let navigate = useNavigate();
	
	const {user_id} = useParams();

	const [user, setUser] = useState({
		first_name : '',
		last_name : '',
		email : ''
	});

	const handleChange = (event) => {
		const {name, value} = event.target;

		setUser({
			...user,
			[name] : value
		});
	};

	const fetchUserData = () => {
		fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`)
		.then((response) => response.json())
		.then((data) => {
			setUser(data);
		});
	};

	useEffect(() => {
		fetchUserData();
	}, []);

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6">Edit User</div>
					<div className="col-md-6">
						<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<div className="row">
					<div className="col-md-4">&nbsp;</div>
					<div className="col-md-4">
						<form method="POST">
							<div className="mb-3">
								<label>First Name</label>
								<input type="text" name="first_name" className="form-control" value={user.first_name} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Last Name</label>
								<input type="text" name="last_name" className="form-control" value={user.last_name} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Email</label>
								<input type="email" name="email" className="form-control" value={user.email} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<input type="submit" className="btn btn-primary" value="Edit" />
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
	)
}

export default Edit;


1 - Import Statements:


import React, {useState, useEffect} from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';


  • The code imports the necessary functionalities from the react and react-router-dom libraries.
  • useParams is used to extract parameters from the URL.

2 - Component Definition:


function Edit() {


  • The functional component named Edit is defined.

3 - Hooks and State Initialization:


let navigate = useNavigate();

const [user, setUser] = useState({
    first_name: '',
    last_name: '',
    email: ''
});


  • The useNavigate hook is used to get the navigate function for programmatic navigation.
  • The useState hook initializes the user state, representing user information with properties first_name, last_name, and email.

4 - Event Handler Function (handleChange):


const handleChange = (event) => {
    const { name, value } = event.target;

    setUser({
        ...user,
        [name]: value
    });
};

  • The handleChange function is an event handler for input changes. It updates the user state based on the changed input field.

5 - Fetch User Data Function (fetchUserData):


const fetchUserData = () => {
    fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`)
        .then((response) => response.json())
        .then((data) => {
            setUser(data);
        });
};


  • The fetchUserData function uses the fetch API to retrieve user data based on the id parameter from the URL.
  • The fetched data is then used to update the user state.

6 - UseEffect Hook for Fetching Data:


useEffect(() => {
    fetchUserData();
}, []);


  • The useEffect hook is used to execute the fetchUserData function when the component mounts (empty dependency array []).
  • This ensures that user data is fetched once when the component is rendered.

Rendering JSX:


return (
    <div className="card">
        {/* ... */}
    </div>
);


  • The return statement contains JSX code that represents the structure of the component.

7 - JSX Structure:

  • The component renders a Bootstrap-styled card with a header and body.
  • The body contains a form with input fields for "First Name," "Last Name," and "Email," along with a submit button labeled "Edit."
  • The input values are controlled by the user state, ensuring that the form fields display the current user data.

9 - Navigation Link:


<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>


  • This is a Link component that creates a link to the root path ("/"). It's styled as a Bootstrap button and is labeled "View All."
  • Clicking on this link will navigate the user back to the root path.

10 - Form Input Fields:


<input type="text" name="first_name" className="form-control" value={user.first_name} onChange={handleChange} />
<input type="text" name="last_name" className="form-control" value={user.last_name} onChange={handleChange} />
<input type="email" name="email" className="form-control" value={user.email} onChange={handleChange} />


  • These input fields are controlled components, meaning their values are controlled by the user state.
  • The value attribute is set to the corresponding property of the user state.
  • The onChange event is set to the handleChange function, ensuring that any changes to the input fields update the state.

11 - Submit Button:


<input type="submit" className="btn btn-primary" value="Edit" />


  • This is a submit button for the form. It triggers the submission of the form data.

12 - Export Statement:


export default Edit;


  • The Edit component is exported as the default export of this module, making it available for use in other parts of the application.

In summary, this Edit component is a form for editing user data. It uses the useEffect hook to fetch user data when the component mounts, and it provides a form with controlled input fields. The user can edit the information, and clicking the "Edit" button triggers an update operation, which is typically handled on the server side.

src/App.jsx

import { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import Userlist from './Component/Userlist';
import Add from './Component/Add';
import Edit from './Component/Edit';

function App() {
    return(
        <div className="container">
            <h1 className="mt-5 mb-5 text-center"><b>PHP React.js CRUD Application - <span className="text-primary">Create Delete Data API - 8</span></b></h1>
            <BrowserRouter>
                <Routes>
                    <Route path="/" element={<Userlist />} />
                    <Route path="/add" element={<Add />} />
                    <Route path="/edit/:user_id" element={<Edit />} />
                </Routes>
            </BrowserRouter>
        </div>
    )
}

export default App



  • Component Edit is imported from it's respective file.

<Route path="/edit/:user_id" element={<Edit />} />


  • The third one maps the "/edit/:user_id" path to the Edit component. The :user_id is a dynamic parameter that can be accessed in the Edit component.
api/action.php

<?php

header("Access-Control-Allow-Origin:* ");

header("Access-Control-Allow-Headers:* ");

header("Access-Control-Allow-Methods:* ");

$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");

$method = $_SERVER['REQUEST_METHOD']; //return GET, POST, PUT, DELETE

if($method === 'GET')
{
	if(isset($_GET['id']))
	{
		//fetch single user
		$query = "SELECT * FROM sample_users WHERE id = '".$_GET["id"]."'";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data['first_name'] = $row['first_name'];

			$data['last_name'] = $row['last_name'];

			$data['email'] = $row['email'];

			$data['id'] = $row['id'];
		}

		echo json_encode($data);
	}
	else 
	{
		//fetch all user

		$query = "SELECT * FROM sample_users ORDER BY id DESC";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data[] = $row;
		}

		echo json_encode($data);
	}	
}

if($method === 'POST')
{
	$form_data = json_decode(file_get_contents('php://input'));

	$data = array(
		':first_name'		=>	$form_data->first_name,
		':last_name'		=>	$form_data->last_name,
		':email'			=>	$form_data->email
	);

	$query = "
	INSERT INTO sample_users (first_name, last_name, email) VALUES (:first_name, :last_name, :email);
	";

	$statement = $connect->prepare($query);

	$statement->execute($data);

	echo json_encode(["success" => "done"]);
}

?>


1 - Check for id Parameter:


if(isset($_GET['id']))


  • Checks if the id parameter is set in the query string of the URL. If id parameter value is set then single user data will be fetch otherwise all user data will be fetch.

2 - Fetch Single User Data


//fetch single user
		$query = "SELECT * FROM sample_users WHERE id = '".$_GET["id"]."'";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data['first_name'] = $row['first_name'];

			$data['last_name'] = $row['last_name'];

			$data['email'] = $row['email'];

			$data['id'] = $row['id'];
		}

		echo json_encode($data);


  • If the id parameter is set, it constructs a SQL query to fetch a single user with the specified ID.
  • Executes the SQL query using PDO (PHP Data Objects) to fetch the data associated with the specified user ID.
  • Iterates over the result set and prepares the data for the single user. It assigns the user's first name, last name, email, and ID to the $data array.
  • Encodes the prepared data as JSON and echoes it back as the response.

In summary, this PHP script handles GET requests to fetch user data. If the request includes an id parameter, it fetches a single user; otherwise, it fetches all users. The script uses PDO for database interaction and outputs the result as JSON.




Step 7 - Make Update Data API


After creating Edit Component under this React CRUD Application and fetch single user data. Now you have to learn, how to submit edit user form data under this React application. And then after, We will make API for update user data under this React CRUD application.

src/Component/Edit.jsx

import React, {useState, useEffect} from 'react';

import { Link, useNavigate, useParams } from 'react-router-dom';

function Edit(){

	let navigate = useNavigate();

	const {user_id} = useParams();

	const [user, setUser] = useState({
		first_name : '',
		last_name : '',
		email : ''
	});

	const handleChange = (event) => {
		const {name, value} = event.target;

		setUser({
			...user,
			[name] : value
		});
	};

	const fetchUserData = () => {
		fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`)
		.then((response) => response.json())
		.then((data) => {
			setUser(data);
		});
	};

	useEffect(() => {
		fetchUserData();
	}, []);

	const handleSubmit = (event) => {

		event.preventDefault();

		fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`, {
			method : 'PUT',
			headers : {
				'Content-Type': 'application/json'
			},
			body : JSON.stringify(user)
		})
		.then((response) => response.json())
		.then((data) => {
			navigate("/");
		});

	};

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6">Edit User</div>
					<div className="col-md-6">
						<Link to="/" className="btn btn-success btn-sm float-end">View All</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<div className="row">
					<div className="col-md-4">&nbsp;</div>
					<div className="col-md-4">
						<form method="POST" onSubmit={handleSubmit}>
							<div className="mb-3">
								<label>First Name</label>
								<input type="text" name="first_name" className="form-control" value={user.first_name} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Last Name</label>
								<input type="text" name="last_name" className="form-control" value={user.last_name} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<label>Email</label>
								<input type="email" name="email" className="form-control" value={user.email} onChange={handleChange} />
							</div>
							<div className="mb-3">
								<input type="submit" className="btn btn-primary" value="Edit" />
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
	)
}

export default Edit;


1 - Form Submission Function (handleSubmit):


const handleSubmit = (event) => {
    event.preventDefault();

    fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`, {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(user)
    })
    .then((response) => response.json())
    .then((data) => {
        navigate("/");
    });
};


  • The handleSubmit function is called when the form is submitted.
  • It prevents the default form submission, sends a PUT request to update the user data, and then navigates to the root path (/) using the navigate function.

2 - Call JavaScript handleSubmit function


<form method="POST" onSubmit={handleSubmit}>
  {/* Form contents go here */}
</form>


  • The onSubmit attribute is set to a JavaScript function handleSubmit. This function will be called when the form is submitted.
  • The handleSubmit function is expected to handle the form submission logic. It usually includes tasks such as preventing the default form submission behavior, gathering form data, and sending it to the server.
api/action.php

<?php

header("Access-Control-Allow-Origin:* ");

header("Access-Control-Allow-Headers:* ");

header("Access-Control-Allow-Methods:* ");

$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");

$method = $_SERVER['REQUEST_METHOD']; //return GET, POST, PUT, DELETE

if($method === 'GET')
{
	if(isset($_GET['id']))
	{
		//fetch single user
		$query = "SELECT * FROM sample_users WHERE id = '".$_GET["id"]."'";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data['first_name'] = $row['first_name'];

			$data['last_name'] = $row['last_name'];

			$data['email'] = $row['email'];

			$data['id'] = $row['id'];
		}

		echo json_encode($data);
	}
	else 
	{
		//fetch all user

		$query = "SELECT * FROM sample_users ORDER BY id DESC";

		$result = $connect->query($query, PDO::FETCH_ASSOC);

		$data = array();

		foreach($result as $row)
		{
			$data[] = $row;
		}

		echo json_encode($data);
	}

	
}

if($method === 'POST')
{
	//Insert User Data

	$form_data = json_decode(file_get_contents('php://input'));

	$data = array(
		':first_name'		=>	$form_data->first_name,
		':last_name'		=>	$form_data->last_name,
		':email'			=>	$form_data->email
	);

	$query = "
	INSERT INTO sample_users (first_name, last_name, email) VALUES (:first_name, :last_name, :email);
	";

	$statement = $connect->prepare($query);

	$statement->execute($data);

	echo json_encode(["success" => "done"]);
}

if($method === 'PUT')
{
	//Update User Data

	$form_data = json_decode(file_get_contents('php://input'));

	$data = array(
		':first_name'		=>	$form_data->first_name,
		':last_name'		=>	$form_data->last_name,
		':email'			=>	$form_data->email,
		':id'				=>	$form_data->id
	);

	$query = "
	UPDATE sample_users 
	SET first_name = :first_name, 
	last_name = :last_name, 
	email = :email 
	WHERE id = :id
	";

	$statement = $connect->prepare($query);

	$statement->execute($data);

	echo json_encode(["success" => "done"]);
}
?>


This PHP code handles the logic for updating user data when the HTTP request method is PUT.

1 - Check Request Method:


if ($method === 'PUT') {
    // Update User Data
    // ...
}


  • This block checks if the HTTP request method is PUT. If true, it proceeds to handle the update operation.

2 - Decode JSON Data:


$form_data = json_decode(file_get_contents('php://input'));


  • Reads and decodes JSON data from the request body sent by the client. This data likely contains information about the user to be updated, including the new values for first_name, last_name, email, and id.

3 - Prepare Data for Update:


$data = array(
    ':first_name' => $form_data->first_name,
    ':last_name'  => $form_data->last_name,
    ':email'      => $form_data->email,
    ':id'         => $form_data->id
);


  • Creates an associative array ($data) with placeholders for the values to be updated in the SQL query.

4 - SQL Update Query:


$query = "
UPDATE sample_users 
SET first_name = :first_name, 
last_name = :last_name, 
email = :email 
WHERE id = :id
";


  • Defines an SQL query to update the user data in the sample_users table. The placeholders :first_name, :last_name, :email, and :id will be replaced with the corresponding values from the $data array.

5 - Prepare and Execute SQL Statement:


$statement = $connect->prepare($query);
$statement->execute($data);


  • Prepares the SQL statement using the PDO extension.
  • Executes the prepared statement with the data provided. This updates the user data in the database.

6 - JSON Response:


echo json_encode(["success" => "done"]);


  • Outputs a JSON response indicating the success of the update operation. This response is sent back to the client.

In summary, when a PUT request is received, this PHP code decodes the JSON data sent by the client, prepares the data for the update, executes an SQL query to update the user data in the database, and sends a JSON response indicating the success of the operation.




Step 8 - Create Delete Data API


Now we have come to last step of this React.js PHP CRUD Application and under this step you can find how to delete data from MySQL table by using PHP API and React.js function.

src/Component/Userlist.jsx

import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

function Userlist(){
	const [users, setUsers] = useState([]);

	useEffect(() => {
		const apiUrl = 'http://localhost/tutorial/phpreactcrud/api/action.php';

		fetch(apiUrl)
		.then((response) => response.json())
		.then((data) => {
			setUsers(data);
		});

	}, []);

	const handleDelete = (user_id) => {
		if(confirm("Are your sure you want to remove it?"))
		{
			fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`, {
				method : 'DELETE'
			})
			.then((response) => response.json())
			.then((data) => {
				setUsers((prevUser) => prevUser.filter((user) => user.id !== user_id));
			});
		}
	};

	return (
		<div className="card">
			<div className="card-header">
				<div className="row">
					<div className="col-md-6"><b>User Data</b></div>
					<div className="col-md-6">
						<Link to="/add" className="btn btn-success btn-sm float-end">Add</Link>
					</div>
				</div>
			</div>
			<div className="card-body">
				<table className="table table-bordered">
					<thead>
						<tr>
							<th>First Name</th>
							<th>Last Name</th>
							<th>Email</th>
							<th>Action</th>
						</tr>
					</thead>
					<tbody>
					{users.map((user, index) => (
						<tr key={index}>
							<td>{user.first_name}</td>
							<td>{user.last_name}</td>
							<td>{user.email}</td>
							<td>
								<Link to={`/edit/${user.id}`} className="btn btn-warning btn-sm">Edit</Link>&nbsp;
								<button type="button" onClick={() => handleDelete(user.id)} className="btn btn-danger btn-sm">Delete</button>
							</td>
						</tr>
					))}
					</tbody>
				</table>
			</div>
		</div>
	);
}

export default Userlist;


1 - Delete User Handler:


const handleDelete = (user_id) => {
		if(confirm("Are your sure you want to remove it?"))
		{
			fetch(`http://localhost/tutorial/phpreactcrud/api/action.php?id=${user_id}`, {
				method : 'DELETE'
			})
			.then((response) => response.json())
			.then((data) => {
				setUsers((prevUser) => prevUser.filter((user) => user.id !== user_id));
			});
		}
	};


  • Defines a function handleDelete to handle the deletion of a user.
  • Prompts the user with a confirmation dialog before proceeding with the deletion.
  • Sends a DELETE request to the server API with the user ID to be deleted.
  • Updates the users state by removing the deleted user from the array.

2 - Create Delete Button


<button type="button" onClick={() => handleDelete(user.id)} className="btn btn-danger btn-sm">Delete</button>


  • "Delete" button triggers the handleDelete function when clicked.
api/action.php

if($method === 'DELETE')
{
	//Delete User Data
	
	$data = array(
		':id' => $_GET['id']
	);

	$query = "DELETE FROM sample_users WHERE id = :id";

	$statement = $connect->prepare($query);

	$statement->execute($data);

	echo json_encode(["success" => "done"]);
}


This PHP code handles the logic for deleting a user when the HTTP request method is DELETE.

1 - Check Request Method:


if ($method === 'DELETE') {
    // Delete User Data
    // ...
}


  • This block checks if the HTTP request method is DELETE. If true, it proceeds to handle the delete operation.

2 - Prepare Data for Deletion:


$data = array(
    ':id' => $_GET['id']
);


  • Creates an associative array ($data) with a placeholder (:id) for the user ID to be deleted. The user ID is obtained from the query parameters ($_GET['id']).

3 - SQL Delete Query:


$query = "DELETE FROM sample_users WHERE id = :id";


  • Defines an SQL query to delete a user from the sample_users table based on the provided user ID.

4 - Prepare and Execute SQL Statement:


$statement = $connect->prepare($query);
$statement->execute($data);


  • Prepares the SQL statement using the PDO extension.
  • Executes the prepared statement with the data provided. This deletes the user from the database.

5 - JSON Response:


echo json_encode(["success" => "done"]);


  • Outputs a JSON response indicating the success of the delete operation. This response is sent back to the client.

In summary, when a DELETE request is received, this PHP code prepares the user ID for deletion, executes an SQL query to delete the user data from the database, and sends a JSON response indicating the success of the delete operation.




Conclusion


Congratulations! You've successfully built a full-stack CRUD application using React.js, Vite, PHP, and MySQL. This project provides a solid foundation for more complex applications, and you can further enhance it by adding features like authentication, error handling, and improved user interfaces.

Remember to follow best practices for security, such as validating and sanitizing user input on the server side, securing your database connections, and implementing proper authentication mechanisms. Happy coding!