article

Friday, October 21, 2022

React CRUD (Create Read Update and Delete) with PHP MySQL

React CRUD (Create Read Update and Delete) with PHP MySQL

Create Project
C:\react>npx create-react-app demo-project

Run
C:\react\my-app> npm start

Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react\my-app>npm i react-router-dom --save

Install Axios
https://www.npmjs.com/package/axios
C:\react\my-app>npm install axios --save


C:\react\demo-project\src\App.js
//C:\react\demo-project\src\App.js
import {BrowserRouter, Routes, Route, Link} from 'react-router-dom'; //npm i react-router-dom --save
import './App.css';
import CreateUser from './components/CreateUser';
import EditUser from './components/EditUser';
import ListUser from './components/ListUser';

function App() {
  return (
	<div className="container">
    <div className="App">
      <h1 class="page-header text-center">React CRUD (Create Read Update and Delete) with PHP MySQL</h1>

      <BrowserRouter>
		<Link to="user/create" className="btn btn-success">Add New User</Link>

        <Routes>
          <Route index element={<ListUser />} />
          <Route path="user/create" element={<CreateUser />} />
          <Route path="user/:id/edit" element={<EditUser />} />
        </Routes>
      </BrowserRouter>
    </div>
    </div>
  );
}

export default App;
C:\react\demo-project\public\index.html
//C:\react\demo-project\public\index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
	<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"/>
	<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
C:\react\demo-project\src\components\ListUser.js
//C:\react\demo-project\src\components\ListUser.js
import axios from "axios" //npm install axios --save
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

export default function ListUser() {

    const [users, setUsers] = useState([]);
    useEffect(() => {
        getUsers();
    }, []);

    function getUsers() {
        axios.get('http://localhost/react/api/').then(function(response) {
            console.log(response.data);
            setUsers(response.data);
        });
    }

    const deleteUser = (id) => {
        axios.delete(`http://localhost/react/api/${id}/delete`).then(function(response){
            console.log(response.data);
            getUsers();
        });
    }
    return (
		<div className="row">
			<div className="col-12">
            <h1>List Users</h1>
            <table class="table table-bordered table-striped">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Mobile</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {users.map((user, key) =>
                        <tr key={key}>
                            <td>{user.id}</td>
                            <td>{user.name}</td>
                            <td>{user.email}</td>
                            <td>{user.mobile}</td>
                            <td>
                                <Link to={`user/${user.id}/edit`} className="btn btn-success" style={{marginRight: "10px"}}>Edit</Link>
                                <button onClick={() => deleteUser(user.id)} className="btn btn-danger">Delete</button>
                            </td>
                        </tr>
                    )}
                    
                </tbody>
            </table>
			</div>
        </div>
    )
}
C:\react\demo-project\src\components\EditUser.js
//C:\react\demo-project\src\components\EditUser.js
import { useState, useEffect } from "react";
import axios from "axios";
import { useNavigate, useParams } from "react-router-dom";

export default function ListUser() {
    const navigate = useNavigate();

    const [inputs, setInputs] = useState([]);

    const {id} = useParams();

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

    function getUser() {
        axios.get(`http://localhost/react/api/${id}`).then(function(response) {
            console.log(response.data);
            setInputs(response.data);
        });
    }

    const handleChange = (event) => {
        const name = event.target.name;
        const value = event.target.value;
        setInputs(values => ({...values, [name]: value}));
    }
    const handleSubmit = (event) => {
        event.preventDefault();

        axios.put(`http://localhost/react/api/${id}/edit`, inputs).then(function(response){
            console.log(response.data);
            navigate('/');
        });
        
    }
    return (
        <div className="row">
			<div className="col-2"></div>
			<div className="col-8">
            <h1>Edit user</h1>
            <form onSubmit={handleSubmit}>
				<div className="mb-3">
				  <label>Name</label>
				  <input type="text" value={inputs.name} className="form-control" name="name" onChange={handleChange} />
				</div>
				<div className="mb-3">
				  <label>Email</label>
				  <input type="text" value={inputs.email} className="form-control" name="email" onChange={handleChange} />
				</div>
				<div className="mb-3">
				  <label>Mobile</label>
				  <input type="text" value={inputs.mobile} className="form-control" name="mobile" onChange={handleChange} />
				</div>	
				<button type="submit" name="update" className="btn btn-primary">Save</button>
            </form>
			</div>
			<div className="col-2"></div>
        </div>
    )
}
C:\react\demo-project\src\components\CreateUser.js
//C:\react\demo-project\src\components\CreateUser.js
import { useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";

export default function ListUser() {
    const navigate = useNavigate();

    const [inputs, setInputs] = useState([]);

    const handleChange = (event) => {
        const name = event.target.name;
        const value = event.target.value;
        setInputs(values => ({...values, [name]: value}));
    }
    const handleSubmit = (event) => {
        event.preventDefault();

        axios.post('http://localhost/react/api/save', inputs).then(function(response){
            console.log(response.data);
            navigate('/');
        });
        
    }
    return (
        <div className="row">
			<div className="col-2"></div>
			<div className="col-8">
            <h1>Create user</h1>
            <form onSubmit={handleSubmit}>
				<div className="mb-3">
				  <label>Name</label>
				  <input type="text" className="form-control" name="name" onChange={handleChange} />
				</div>
				<div className="mb-3">
				  <label>Email</label>
				  <input type="text" className="form-control" name="email" onChange={handleChange} />
				</div>
				<div className="mb-3">
				  <label>Mobile</label>
				  <input type="text" className="form-control" name="mobile" onChange={handleChange} />
				</div>	
				<button type="submit" name="add" className="btn btn-primary">Save</button>
            </form>
			</div>
			<div className="col-2"></div>
        </div>
    )
}
database table

CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(150) NOT NULL,
`email` varchar(150) NOT NULL,
`mobile` varchar(150) NOT NULL,
`created_at` date NOT NULL,
`updated_at` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `users` (`id`, `name`, `email`, `mobile`, `created_at`, `updated_at`) VALUES
(1, 'Cairococers Ednalan', 'cairocoders@gmail.com', '123456789', '2022-10-21', '2022-10-21'),
(2, 'Airi Satou', 'AiriSatou@gmail.com', '123446465', '2022-10-21', '2022-10-22'),
(3, 'Clydey Ednalan', 'clydeyednalan@gmail.com', '3546565', '2022-10-22', '0000-00-00'),
(4, 'Angelica Ramos', 'AngelicaRamos@gmail.com', '53465465', '2022-10-22', '0000-00-00'),
(5, 'Ashton Cox', 'AshtonCox@gmail.com', '354656', '2022-10-22', '0000-00-00'),
(6, 'Bradley Greer', 'BradleyGreer@gmail.com', '544665', '2022-10-22', '0000-00-00'),
(7, 'Brenden Wagner', 'BrendenWagner@gmail.com', '35443554', '2022-10-22', '0000-00-00'),
(8, 'Brielle Williamson', 'BrielleWilliamson@gmail.com', '3546', '2022-10-22', '0000-00-00'),
(9, 'Bruno Nash', 'BrunoNashgmail.com', '5465465', '2022-10-22', '0000-00-00'),
(10, 'Caesar Vance', 'CaesarVance@gmail.com', '46465', '2022-10-22', '0000-00-00'),
(11, 'Cara Stevens', 'CaraStevens@gmail.com', '465465', '2022-10-22', '0000-00-00'),
(12, 'Cedric Kelly ', 'CedricKelly@gmail.com', '354564', '2022-10-22', '2022-10-22');

ALTER TABLE `users`
ADD PRIMARY KEY (`id`);

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

C:\xampp\htdocs\react\api\index.php
//C:\xampp\htdocs\react\api\index.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");

include 'DbConnect.php';
$objDb = new DbConnect;
$conn = $objDb->connect();

$method = $_SERVER['REQUEST_METHOD'];
switch($method) {
    case "GET":
        $sql = "SELECT * FROM users";
        $path = explode('/', $_SERVER['REQUEST_URI']);
        if(isset($path[3]) && is_numeric($path[3])) {
            $sql .= " WHERE id = :id";
            $stmt = $conn->prepare($sql);
            $stmt->bindParam(':id', $path[3]);
            $stmt->execute();
            $users = $stmt->fetch(PDO::FETCH_ASSOC);
        } else {
            $stmt = $conn->prepare($sql);
            $stmt->execute();
            $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        echo json_encode($users);
        break;
    case "POST":
        $user = json_decode( file_get_contents('php://input') );
        $sql = "INSERT INTO users(id, name, email, mobile, created_at) VALUES(null, :name, :email, :mobile, :created_at)";
        $stmt = $conn->prepare($sql);
        $created_at = date('Y-m-d');
        $stmt->bindParam(':name', $user->name);
        $stmt->bindParam(':email', $user->email);
        $stmt->bindParam(':mobile', $user->mobile);
        $stmt->bindParam(':created_at', $created_at);

        if($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record created successfully.'];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to create record.'];
        }
        echo json_encode($response);
        break;

    case "PUT":
        $user = json_decode( file_get_contents('php://input') );
        $sql = "UPDATE users SET name= :name, email =:email, mobile =:mobile, updated_at =:updated_at WHERE id = :id";
        $stmt = $conn->prepare($sql);
        $updated_at = date('Y-m-d');
        $stmt->bindParam(':id', $user->id);
        $stmt->bindParam(':name', $user->name);
        $stmt->bindParam(':email', $user->email);
        $stmt->bindParam(':mobile', $user->mobile);
        $stmt->bindParam(':updated_at', $updated_at);

        if($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record updated successfully.'];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to update record.'];
        }
        echo json_encode($response);
        break;


    case "DELETE":
        $sql = "DELETE FROM users WHERE id = :id";
        $path = explode('/', $_SERVER['REQUEST_URI']);

        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $path[3]);

        if($stmt->execute()) {
            $response = ['status' => 1, 'message' => 'Record deleted successfully.'];
        } else {
            $response = ['status' => 0, 'message' => 'Failed to delete record.'];
        }
        echo json_encode($response);
        break;
}
C:\xampp\htdocs\react\api\DbConnect.php
//C:\xampp\htdocs\react\api\DbConnect.php
<?php
	class DbConnect {
		private $server = 'localhost';
		private $dbname = 'reactDB';
		private $user = 'root';
		private $pass = '';

		public function connect() {
			try {
				$conn = new PDO('mysql:host=' .$this->server .';dbname=' . $this->dbname, $this->user, $this->pass);
				$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
				return $conn;
			} catch (\Exception $e) {
				echo "Database Error: " . $e->getMessage();
			}
		}
        
	}
?>
C:\xampp\htdocs\react\api\.htaccess
//C:\xampp\htdocs\react\api\.htaccess
RewriteEngine On

# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Run C:\react\my-app>npm start
Check API Results in Postman
https://www.postman.com/downloads/

POST method : http://localhost/react/api/save
Get method : http://localhost/react/api
PUT method : http://localhost/react/api/1
DELTE method : http://localhost/react/api/1

Related Post