Cara menggunakan hooks in php codeigniter

Pada tutorial ini Anda akan belajar bagaimana membuat aplikasi Create-Read-Update-Delete (CRUD) menggunakan CodeIgniter 4 di sisi backend dan React JS di sisi frontend.

Tidak hanya itu,

Saya juga akan berbagi kepada Anda bagaimana penggunaan Bulma CSS untuk style User Interface (UI).

Dengan demikian, aplikasi yang dibangun menjadi lebih elegan, responsive, dan user friendly.

Mari kita mulai.

Step #1. Install CodeIgniter 4

Untuk menginstal CodeIgniter 4 dapat dilakukan dengan 2 cara yaitu: Instalasi manual dan Instalasi menggunakan composer.

Pada tutorial ini, saya akan menggunakan composer.

Jika Anda belum memiliki composer, silahkan kunjungi URL berikut untuk mendownload composer, kemudian install di komputer Anda:

https://getcomposer.org/

Setelah composer terinstall di komputer Anda dan untuk memastikan composer terinstall dengan baik di komputer Anda, buka terminal atau Command Prompt (CMD).

Kemudian ketikan perintah berikut:

composer -v

Seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Setelah composer terinstal dengan baik di komputer Anda, kemudian Anda dapat membuat project CodeIgniter 4 menggunakan composer.

Buat sebuah folder di web server Anda, disini saya beri nama “fullstack”.

Jika Anda menggunakan WAMPSERVER, buat di folder:

C:/wamp64/www

Jika Anda menggunakan XAMPP, buat di folder:

C:/xampp/htdocs

Pada tutorial ini, saya menggunakan XAMPP.

Kemudian buka folder “fullstack” tersebut menggunakan Code Editor, disini saya menggunakan Visual Studio Code.

Setelah itu, integrasikan dengan terminal pada VS Code.

Kemudian ketikan perintah berikut pada terminal untuk membuat project CodeIgniter 4:

composer create-project codeigniter4/appstarter backend

Tunggu sampai proses instalasinya selesai.

Setelah instalasi selesai, masuk ke folder “backend” dengan mengetikan perintah berikut pada terminal:

cd backend

Kemudian ketikan perintah berikut pada terminal untuk menjalankan project:

php spark serve

Jika berjalan dengan baik, maka akan tampil tampilan seperti berikut:

Cara menggunakan hooks in php codeigniter

Dapatkan diskon 75% paket hosting dan gratis domain + extra diskon 5% dengan menggunakan kupon: MFIKRI

Order Sekarang.!

Step #2. Buat Database dan Table

Buat sebuah database baru pada MySQL, Anda dapat menggunakan tools seperti SQLyog, PHPMyAdmin atau sejenisnya.

Disini saya membuat database dengan nama “fullstack_db”.

Jika Anda membuat database dengan nama yang sama itu lebih baik.

Untuk  membuat database pada MySQL, dapat dilakukan dengan mengeksekusi query berikut:

CREATE DATABASE fullstack_db;

Perintah SQL diatas akan membuat sebuah database dengan nama “fullstack_db”.

Selanjutnya, buat koneksi antara database dengan project CodeIgniter 4.

Temukan file env pada root project, kemudian rename (ganti nama) menjadi .env dan open file tersebut.

Kemudian temukan kode berikut:

# database.default.hostname = localhost
# database.default.database = ci4
# database.default.username = root
# database.default.password = root
# database.default.DBDriver = MySQLi

Ubah menjadi seperti berikut:

database.default.hostname = localhost
database.default.database = fullstack_db
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi

Selanjutnya adalah pembuatan table pada database “fullstack_db”.

Pada tutorial ini, saya akan menggunakan fitur migration pada CodeIgniter 4 untuk pembuatan table.

Ketikan perintah berikut pada Terminal/Command Prompt:

php spark make:migration Products

Kemudian Enter, maka CodeIgniter akan membuat sebuah file berinisial “Products” pada folder “app/Database/Migrations”.

Seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Buka file tersebut, kemudian ketikan kode berikut:

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Products extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type' => 'INT',
                'constraint' => 5,
                'auto_increment' => true
            ],
            'title' => [
                'type' => 'VARCHAR',
                'constraint' => 200,
            ],
            'price' => [
                'type' => 'INT',
                'constraint' => 11,
            ],
        ]);
        $this->forge->addKey('id', true);
        $this->forge->createTable('products');
    }

    public function down()
    {
        //
    }
}

Pada kode diatas, kita hanya menambahkan kode pada function up().

Function up, berfungsi untuk membuat table di database dengan field yang ditetapkan.

Pada kasus diatas, kita membuat sebuah table dengan nama “products” dengan field id, title, dan price beserta type data dan atribut lainnya.

Selanjutnya, ketikan perintah berikut pada Terminal/Command Prompt:

php spark migrate

Kemudian Enter, maka CodeIgniter akan otomatis membuat table “products” dengan field id, title, dan price di dalam database “fullstack_db”.

Step #3. Models

Buat sebuah file model dengan cara mengetikan perintah berikut pada terminal:

php spark make:model ProductModel

Maka secara otomatis CodeIgniter akan membuat sebuah file model bernama “ProductModel.php” di dalam folder “app/Models”.

Kemudian, open file tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Models;

use CodeIgniter\Model;

class ProductModel extends Model
{
    protected $DBGroup              = 'default';
    protected $table                = 'products';
    protected $primaryKey           = 'id';
    protected $useAutoIncrement     = true;
    protected $insertID             = 0;
    protected $returnType           = 'array';
    protected $useSoftDeletes       = false;
    protected $protectFields        = true;
    protected $allowedFields        = ['title','price'];

    // Dates
    protected $useTimestamps        = false;
    protected $dateFormat           = 'datetime';
    protected $createdField         = 'created_at';
    protected $updatedField         = 'updated_at';
    protected $deletedField         = 'deleted_at';

    // Validation
    protected $validationRules      = [];
    protected $validationMessages   = [];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks       = true;
    protected $beforeInsert         = [];
    protected $afterInsert          = [];
    protected $beforeUpdate         = [];
    protected $afterUpdate          = [];
    protected $beforeFind           = [];
    protected $afterFind            = [];
    protected $beforeDelete         = [];
    protected $afterDelete          = [];
}

Pada kode di atas, kita hanya melakukan sedikit perubahan yaitu pada allowedFields.

Step #4. Controllers

Buat sebuah file controller dengan cara mengetikan perintah berikut pada terminal:

php spark make:controller Products --restful

Maka secara otomatis CodeIgniter akan membuat sebuah file controller bernama “Products.php” di dalam folder “app/Controllers”.

Kemudian, open file tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\ProductModel;

class Products extends ResourceController
{
    /**
     * Return an array of resource objects, themselves in array format
     *
     * @return mixed
     */
    use ResponseTrait;
    public function index()
    {
        $model = new ProductModel();
        $data = $model->findAll();
        return $this->respond($data);
    }

    /**
     * Return the properties of a resource object
     *
     * @return mixed
     */
    public function show($id = null)
    {
        $model = new ProductModel();
        $data = $model->find(['id' => $id]);
        if(!$data) return $this->failNotFound('No Data Found');
        return $this->respond($data[0]);
    }

    /**
     * Create a new resource object, from "posted" parameters
     *
     * @return mixed
     */
    public function create()
    {
        helper(['form']);
        $rules = [
            'title' => 'required',
            'price' => 'required'
        ];
        $data = [
            'title' => $this->request->getVar('title'),
            'price' => $this->request->getVar('price')
        ];
        if(!$this->validate($rules)) return $this->fail($this->validator->getErrors());
        $model = new ProductModel();
        $model->save($data);
        $response = [
            'status' => 201,
            'error' => null,
            'messages' => [
                'success' => 'Data Inserted'
            ]
        ];
        return $this->respondCreated($response);
    }

    /**
     * Add or update a model resource, from "posted" properties
     *
     * @return mixed
     */
    public function update($id = null)
    {
        helper(['form']);
        $rules = [
            'title' => 'required',
            'price' => 'required'
        ];
        $data = [
            'title' => $this->request->getVar('title'),
            'price' => $this->request->getVar('price')
        ];
        if(!$this->validate($rules)) return $this->fail($this->validator->getErrors());
        $model = new ProductModel();
        $findById = $model->find(['id' => $id]);
        if(!$findById) return $this->failNotFound('No Data Found');
        $model->update($id, $data);
        $response = [
            'status' => 200,
            'error' => null,
            'messages' => [
                'success' => 'Data Updated'
            ]
        ];
        return $this->respond($response);
    }

    /**
     * Delete the designated resource object from the model
     *
     * @return mixed
     */
    public function delete($id = null)
    {
        $model = new ProductModel();
        $findById = $model->find(['id' => $id]);
        if(!$findById) return $this->failNotFound('No Data Found');
        $model->delete($id);
        $response = [
            'status' => 200,
            'error' => null,
            'messages' => [
                'success' => 'Data Deleted'
            ]
        ];
        return $this->respond($response);
    }
}

Step #5. Konfigurasi Routes.php

Lakukan sedikit konfigurasi pada file Routes.php yang terdapat pada folder “app/Config”.

Buka file “Routes.php” pada folder “app/Config”, kemudian temukan kode berikut:

$routes->get('/', 'Home::index');

Kemudian, ganti menjadi berikut:

$routes->resource('products');

Step #6. CORS (Cross-Origin Resources Sharing)

Ini penting!

Buat sebuah file filter untuk CORS (Cross-Origin Resource Sharing) agar API kita dapat diakses dari luar domain.

Untuk membuat filter CORS, jalankan perintah berikut pada terminal:

php spark make:filter Cors

Maka secara otomatis CodeIgniter akan membuat sebuah file filter bernama “Cors.php” di dalam folder “app/Filters”.

Kemudian, open file “Cors.php” tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class Cors implements FilterInterface
{
    /**
     * Do whatever processing this filter needs to do.
     * By default it should not return anything during
     * normal execution. However, when an abnormal state
     * is found, it should return an instance of
     * CodeIgniterHTTPResponse. If it does, script
     * execution will end and that Response will be
     * sent back to the client, allowing for error pages,
     * redirects, etc.
     *
     * @param RequestInterface $request
     * @param array|null       $arguments
     *
     * @return mixed
     */
    public function before(RequestInterface $request, $arguments = null)
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Headers: X-API-KEY, Origin,X-Requested-With, Content-Type, Accept, Access-Control-Requested-Method, Authorization");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PATCH, PUT, DELETE");
        $method = $_SERVER['REQUEST_METHOD'];
        if($method == "OPTIONS"){
            die();
        }
    }

    /**
     * Allows After filters to inspect and modify the response
     * object as needed. This method does not allow any way
     * to stop execution of other after filters, short of
     * throwing an Exception or Error.
     *
     * @param RequestInterface  $request
     * @param ResponseInterface $response
     * @param array|null        $arguments
     *
     * @return mixed
     */
    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        //
    }
}

Kemudian, buka file “Filters.php” yang terdapat pada folder “app/Config”, kemudian tambah filter cors-nya seperti berikut:

public $aliases = [
    'csrf'     => CSRF::class,
    'toolbar'  => DebugToolbar::class,
    'honeypot' => Honeypot::class,
    'cors'     => App\Filters\Cors::class,
];

Selanjutnya, definisikan “cors” pada public $globals seperti berikut:

public $globals = [
    'before' => [
        // 'honeypot',
        // 'csrf',
        'cors'
    ],
    'after' => [
        'toolbar',
        // 'honeypot',
    ],
];

Step #7. Front-End (React JS)

Untuk front-end, saya akan menggunakan React JS.

Jika Anda belum familiar dengan React JS, saya sarankan untuk mempelajari “Tutorial React JS Untuk Pemula” terlebih dahulu.

Untuk membuat project react js, dapat dilakukan dengan banyak cara.

Akan tetapi cara yang paling mudah adalah “create react app”.

Untuk dapat menjalankan perintah “create-react-app”, Anda hanya perlu menginstall node.js di komputer Anda.

Anda mendownload node.js pada link berikut dan install di komputer Anda:

https://nodejs.org/en/

Setelah node.js terinstall di komputer Anda, buka Command Prompt atau terminal kemudian ketikkan perintah berikut untuk memastikan node.js terinstall dengan baik di komputer Anda:

node -v

Kemudian ketikan perintah berikut untuk memastikan NPM (Node Package Manager) juga terinstall dengan baik:

npm -v

Perhatikan gambar berikut untuk lebih jelasnya:

Cara menggunakan hooks in php codeigniter

Setelah node.js dan npm terinstall dengan baik di komputer Anda, kemudian buka new terminal dan buat project react baru dengan mengetikan perintah berikut pada terminal:

npx create-react-app frontend

Dan pastikan Anda berada di folder “fullstack”, seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Jika instalasi selesai, maka akan terdapat folder “frontend” di dalam folder “fullstack”.

Sehingga di dalam folder “fullstack” terdapat dua folder yaitu: “backend” dan “frontend” seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Folder “backend” merupakan folder aplikasi yang dibangun sebelumnya menggunakan CodeIgniter 4, sedangkan “frontend” merupakan folder aplikasi yang dibuat menggunakan React JS.

Selanjutnya, masuk kedalam folder “frontend” dengan mengetikan perintah berikut pada terminal:

cd frontend

Setelah itu, install react-router-dom, axios, dan bulma dengan mengetikan perintah berikut pada terminal:

npm install react-router-dom axios bulma

Setelah instalasi selesai, dan untuk memastikan semuanya berjalan dengan baik, ketikan perintah berikut untuk menjalankan project:

npm start

Jika berjalan dengan baik, maka akan tampil seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Kemudian, buka browser Anda dan kunjungi URL berikut:

http://localhost:3000

Maka akan tampil seperti berikut:

Cara menggunakan hooks in php codeigniter

Step #8. Components

Buat sebuah folder bernama “components” di dalam folder “frontend/src”.

Kemudian, buat file components “ProductList.js”, “AddProduct.js”, dan “EditProduct.js” pada folder “frontend/src/components”.

Seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

Kemudian buka file “ProductList.js”, kemudian ketikan kode berikut:

/* eslint-disable react-hooks/exhaustive-deps */
import React, { useState, useEffect } from 'react'
import axios from "axios";
import { Link } from "react-router-dom";

const ProductList = () => {
    const [products, setProducts] = useState([]);

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

    const getProducts = async () => {
        const products = await axios.get('http://localhost:8080/products');
        setProducts(products.data);
    }

    const deleteProduct = async (id) =>{
        await axios.delete(`http://localhost:8080/products/${id}`);
        getProducts();
    }

    return (
        <div>
            <Link to="/add" className="button is-primary mt-5">Add New</Link>
            <table className="table is-striped is-fullwidth">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>Title</th>
                        <th>Price</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    { products.map((product, index) => (
                        <tr key={product.id}>
                            <td>{index + 1}</td>
                            <td>{product.title}</td>
                            <td>{product.price}</td>
                            <td>
                                <Link to={`/edit/${product.id}`} className="button is-small is-info">Edit</Link>
                                <button onClick={() => deleteProduct(product.id)} className="button is-small is-danger">Delete</button>
                            </td>
                        </tr>
                    )) }
                    
                </tbody>
            </table>
        </div>
    )
}

export default ProductList

Selanjutnya, buka file “AddProduct.js”, kemudian ketikan kode berikut:

import React, { useState } from 'react'
import { useHistory } from 'react-router-dom';
import axios from "axios";

const AddProduct = () => {
    const [title, setTitle] = useState('');
    const [price, setPrice] = useState('');
    const history = useHistory();

    const saveProduct = async (e) => {
        e.preventDefault();
        await axios.post('http://localhost:8080/products',{
            title: title,
            price: price
        });
        history.push("/");
    }

    return (
        <div>
            <form onSubmit={ saveProduct }>
                <div className="field">
                    <label className="label">Title</label>
                    <input 
                        type="text" 
                        className="input" 
                        value={ title } 
                        onChange={ (e) => setTitle(e.target.value) }
                        placeholder="Title"
                    />
                </div>
                <div className="field">
                    <label className="label">Price</label>
                    <input 
                        type="text" 
                        className="input" 
                        value={ price } 
                        onChange={ (e) => setPrice(e.target.value) }
                        placeholder="Price"
                    />
                </div>
                <div className="field">
                    <button className="button is-primary">Save</button>
                </div>
            </form>
        </div>
    )
}

export default AddProduct

Selanjutnya, buka file “EditProduct.js”, kemudian ketikan kode berikut:

/* eslint-disable react-hooks/exhaustive-deps */
import React, { useState, useEffect } from 'react'
import { useHistory, useParams } from 'react-router-dom';
import axios from "axios";

const EditProduct = () => {
    const [title, setTitle] = useState('');
    const [price, setPrice] = useState('');
    const history = useHistory();
    const { id } = useParams();

    const updateProduct = async (e) => {
        e.preventDefault();
        await axios.patch(`http://localhost:8080/products/${id}`,{
            title: title,
            price: price
        });
        history.push("/");
    }

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

    const getProductById = async () => {
        const response = await axios.get(`http://localhost:8080/products/${id}`);
        setTitle(response.data.title);
        setPrice(response.data.price);
    }

    return (
        <div>
            <form onSubmit={ updateProduct }>
                <div className="field">
                    <label className="label">Title</label>
                    <input 
                        type="text" 
                        className="input" 
                        value={ title } 
                        onChange={ (e) => setTitle(e.target.value) }
                        placeholder="Title"
                    />
                </div>
                <div className="field">
                    <label className="label">Price</label>
                    <input 
                        type="text" 
                        className="input" 
                        value={ price } 
                        onChange={ (e) => setPrice(e.target.value) }
                        placeholder="Price"
                    />
                </div>
                <div className="field">
                    <button className="button is-primary">Update</button>
                </div>
            </form>
        </div>
    )
}

export default EditProduct

Step #9. App.js

Buka file “App.js” pada folder “frontend/src”, kemudian ubah menjadi seperti berikut:

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import ProductList from "./components/ProductList";
import AddProduct from "./components/AddProduct";
import EditProduct from "./components/EditProduct";

function App() {
  return (
    <Router>
      <div className="container">
        <Switch>
          <Route exact path="/">
            <ProductList />
          </Route>
          <Route path="/add">
            <AddProduct />
          </Route>
          <Route path="/edit/:id">
            <EditProduct />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

export default App;

Step #10. index.js

Buka file “index.js” pada folder “frontend/src”, kemudian ubah menjadi seperti berikut:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "bulma/css/bulma.css";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Step #11. Testing

#READ

Kembali ke browser dan kunjungi URL berikut:

http://localhost:3000

Jika berjalan dengan baik, maka akan terlihat seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

#CREATE

Klik tombol “Add New”, maka akan tampil form seperti berikut:

Cara menggunakan hooks in php codeigniter

Masukkan “Title” dan “Price”, kemudian klik tombol “SAVE”.

Jika insert berhasil, maka akan terlihat penambahan data pada list product seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

#UPDATE

Untuk mengupdate data klik salah satu dari tombol “Edit”, maka akan tampil form seperti berikut:

Cara menggunakan hooks in php codeigniter

Ubah “Title” atau “Price”, kemudian klik tombol “UPDATE”.

Jika update berhasil, maka akan terlihat perubahan data pada list product seperti gambar berikut:

Cara menggunakan hooks in php codeigniter

#DELETE 

Untuk menghapus data klik salah satu dari tombol “Delete”.

Jika delete berhasil, maka data akan hilang dari list product.

Related: Tutorial CRUD Node JS, Express, MySQL, dan React JS (Full-Stack)

Kesimpulan:

Pembahasan kali ini adalah bagaimana membuat full stack aplikasi dengan backend CodeIgniter 4 dan frontend menggunakan React JS.

Dengan demikian, Anda telah memiliki gambaran bagaimana membuat aplikasi web modern yang memisahkan antara backend dan frontend.

Jadi tunggu apalagi, Let’s Coding!

Dapatkan diskon 75% paket hosting dan gratis domain + extra diskon 5% dengan menggunakan kupon: MFIKRI

Order Sekarang.!

Download Source Code (Back-End) Download Source Code (Front-End)