Mempelajari konsep pemrograman terstruktur, koneksi database MySQL, dan implementasi operasi CRUD untuk aplikasi web dinamis.
Untuk pemula yang baru belajar database, ikuti urutan ini:
Memahami konsep database dari dasar, struktur database, SQL, dan CRUD dengan analogi yang mudah dipahami.
Panduan lengkap instalasi XAMPP, konfigurasi MySQL, dan setup database siap pakai dengan 7 langkah mudah.
Tutorial implementasi Create, Read, Update, Delete dengan PHP & MySQL lengkap dengan code yang bisa langsung digunakan.
Pemrograman terstruktur menggunakan tiga struktur kontrol dasar: sequence, selection, dan iteration.
Eksekusi berurutan dari atas ke bawah
Percabangan dengan if/else/switch
Perulangan dengan for/while/foreach
<?php
// Fungsi dengan return value
function calculateDiscount($price, $discountPercent) {
if ($discountPercent < 0 || $discountPercent > 100) {
throw new InvalidArgumentException('Discount must be between 0 and 100');
}
return $price * ($discountPercent / 100);
}
// Prosedur (void function)
function displayProductInfo($product) {
echo "<div class='product'>";
echo "<h3>" . htmlspecialchars($product['name']) . "</h3>";
echo "<p>Price: $" . number_format($product['price'], 2) . "</p>";
echo "</div>";
}
// Fungsi dengan multiple parameters dan default values
function formatCurrency($amount, $currency = 'USD', $decimals = 2) {
$symbols = [
'USD' => '$',
'EUR' => '€',
'IDR' => 'Rp'
];
$symbol = $symbols[$currency] ?? $currency;
return $symbol . number_format($amount, $decimals);
}
// Usage examples
try {
$originalPrice = 100;
$discountAmount = calculateDiscount($originalPrice, 15);
$finalPrice = $originalPrice - $discountAmount;
$product = [
'name' => 'Laptop Gaming',
'price' => $finalPrice
];
displayProductInfo($product);
echo formatCurrency($finalPrice, 'IDR');
} catch (Exception $e) {
error_log($e->getMessage());
echo "An error occurred while processing the product.";
}
?>
<?php
// Try-catch block
try {
$result = riskyOperation();
processResult($result);
} catch (DatabaseException $e) {
error_log("Database error: " . $e->getMessage());
showUserError("Database temporarily unavailable");
} catch (ValidationException $e) {
showUserError($e->getMessage());
} catch (Exception $e) {
error_log("Unexpected error: " . $e->getMessage());
showUserError("An unexpected error occurred");
}
// Custom error handler
function customErrorHandler($errno, $errstr, $errfile, $errline) {
error_log("Error [$errno]: $errstr in $errfile on line $errline");
}
set_error_handler('customErrorHandler');
// Debug functions
function debugVariable($var, $label = '') {
echo "<pre>";
if ($label) echo "<strong>$label:</strong>\n";
var_dump($var);
echo "</pre>";
}
?>
// Console debugging methods
console.log('Basic logging');
console.error('Error message');
console.warn('Warning message');
console.info('Info message');
// Object inspection
const user = {name: 'John', age: 30};
console.table(user);
// Performance timing
console.time('operation');
// ... some operation
console.timeEnd('operation');
// Try-catch for JavaScript
function safeOperation() {
try {
const result = JSON.parse(responseData);
return processData(result);
} catch (error) {
console.error('JSON parse error:', error.message);
showUserMessage('Invalid data received');
return null;
}
}
// Debug helper function
function debug(variable, label = '') {
if (typeof variable === 'object') {
console.group(label || 'Debug Object');
console.table(variable);
console.groupEnd();
} else {
console.log(label + ':', variable);
}
}
Structured Query Language (SQL) adalah bahasa standar untuk mengelola database relational.
-- Membuat database
CREATE DATABASE db_mahasiswa;
USE db_mahasiswa;
-- Membuat tabel mahasiswa
CREATE TABLE mahasiswa (
id INT AUTO_INCREMENT PRIMARY KEY,
nim VARCHAR(20) NOT NULL UNIQUE,
nama VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
jurusan VARCHAR(50) NOT NULL,
angkatan YEAR NOT NULL,
alamat TEXT,
tanggal_daftar TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status ENUM('aktif', 'cuti', 'lulus', 'dropout') DEFAULT 'aktif'
);
-- Menambahkan index untuk performa
CREATE INDEX idx_jurusan ON mahasiswa(jurusan);
CREATE INDEX idx_angkatan ON mahasiswa(angkatan);
-- Contoh data sample
INSERT INTO mahasiswa (nim, nama, email, jurusan, angkatan, alamat) VALUES
('2023001001', 'Ahmad Muyassar', 'ahmad@email.com', 'Informatika', 2023, 'Makassar'),
('2023001002', 'Siti Nurhaliza', 'siti@email.com', 'Sistem Informasi', 2023, 'Jakarta'),
('2022001001', 'Budi Santoso', 'budi@email.com', 'Informatika', 2022, 'Surabaya');
-- Basic SELECT
SELECT * FROM mahasiswa;
-- SELECT dengan kondisi
SELECT nama, email FROM mahasiswa
WHERE jurusan = 'Informatika';
-- SELECT dengan ORDER BY
SELECT * FROM mahasiswa
ORDER BY nama ASC;
-- SELECT dengan LIMIT
SELECT * FROM mahasiswa
LIMIT 10 OFFSET 0;
-- SELECT dengan COUNT
SELECT jurusan, COUNT(*) as total
FROM mahasiswa
GROUP BY jurusan;
-- SELECT dengan JOIN (jika ada tabel lain)
SELECT m.nama, m.nim, n.nilai
FROM mahasiswa m
LEFT JOIN nilai n ON m.id = n.mahasiswa_id;
-- INSERT data baru
INSERT INTO mahasiswa (nim, nama, email, jurusan, angkatan)
VALUES ('2023001003', 'Andi Rahman', 'andi@email.com', 'Informatika', 2023);
-- UPDATE data existing
UPDATE mahasiswa
SET alamat = 'Bandung', status = 'aktif'
WHERE nim = '2023001003';
-- DELETE data
DELETE FROM mahasiswa
WHERE status = 'dropout';
-- UPDATE dengan kondisi multiple
UPDATE mahasiswa
SET status = 'lulus'
WHERE angkatan = 2020 AND jurusan = 'Informatika';
-- INSERT multiple rows
INSERT INTO mahasiswa (nim, nama, email, jurusan, angkatan) VALUES
('2023001004', 'Lisa Andriani', 'lisa@email.com', 'Sistem Informasi', 2023),
('2023001005', 'Rudi Hartono', 'rudi@email.com', 'Informatika', 2023);
<?php
// Database configuration
class DatabaseConfig {
const HOST = 'localhost';
const USERNAME = 'root';
const PASSWORD = '';
const DATABASE = 'db_mahasiswa';
const CHARSET = 'utf8mb4';
}
// Database connection class
class Database {
private $connection;
public function __construct() {
try {
$dsn = "mysql:host=" . DatabaseConfig::HOST .
";dbname=" . DatabaseConfig::DATABASE .
";charset=" . DatabaseConfig::CHARSET;
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->connection = new PDO($dsn, DatabaseConfig::USERNAME, DatabaseConfig::PASSWORD, $options);
} catch (PDOException $e) {
error_log("Database connection failed: " . $e->getMessage());
throw new Exception("Database connection failed");
}
}
public function getConnection() {
return $this->connection;
}
// Prepared statement untuk keamanan
public function query($sql, $params = []) {
try {
$stmt = $this->connection->prepare($sql);
$stmt->execute($params);
return $stmt;
} catch (PDOException $e) {
error_log("Query failed: " . $e->getMessage());
throw new Exception("Query execution failed");
}
}
// Get single row
public function fetchOne($sql, $params = []) {
$stmt = $this->query($sql, $params);
return $stmt->fetch();
}
// Get multiple rows
public function fetchAll($sql, $params = []) {
$stmt = $this->query($sql, $params);
return $stmt->fetchAll();
}
// Get last inserted ID
public function lastInsertId() {
return $this->connection->lastInsertId();
}
}
// Usage example
try {
$db = new Database();
// Test connection
$result = $db->fetchOne("SELECT 'Connection successful' as message");
echo $result['message'];
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
CRUD adalah operasi dasar untuk mengelola data dalam aplikasi web.
| ID | NIM | Nama | Jurusan | Aksi |
|---|---|---|---|---|
| 1 | 2023001001 | Ahmad Muyassar | Informatika | |
| 2 | 2023001002 | Siti Nurhaliza | Sistem Informasi |
<?php
class MahasiswaManager {
private $db;
public function __construct(Database $database) {
$this->db = $database;
}
// CREATE - Tambah mahasiswa baru
public function create($data) {
try {
// Validasi data
$this->validateMahasiswaData($data);
$sql = "INSERT INTO mahasiswa (nim, nama, email, jurusan, angkatan, alamat)
VALUES (:nim, :nama, :email, :jurusan, :angkatan, :alamat)";
$params = [
':nim' => $data['nim'],
':nama' => $data['nama'],
':email' => $data['email'],
':jurusan' => $data['jurusan'],
':angkatan' => $data['angkatan'],
':alamat' => $data['alamat'] ?? null
];
$this->db->query($sql, $params);
return $this->db->lastInsertId();
} catch (Exception $e) {
error_log("Create mahasiswa failed: " . $e->getMessage());
throw new Exception("Gagal menambah data mahasiswa");
}
}
// READ - Ambil data mahasiswa
public function getAll($limit = 10, $offset = 0) {
try {
$sql = "SELECT * FROM mahasiswa ORDER BY nama ASC LIMIT :limit OFFSET :offset";
$params = [':limit' => $limit, ':offset' => $offset];
return $this->db->fetchAll($sql, $params);
} catch (Exception $e) {
error_log("Get all mahasiswa failed: " . $e->getMessage());
throw new Exception("Gagal mengambil data mahasiswa");
}
}
public function getById($id) {
try {
$sql = "SELECT * FROM mahasiswa WHERE id = :id";
return $this->db->fetchOne($sql, [':id' => $id]);
} catch (Exception $e) {
error_log("Get mahasiswa by ID failed: " . $e->getMessage());
throw new Exception("Gagal mengambil data mahasiswa");
}
}
public function searchByName($name) {
try {
$sql = "SELECT * FROM mahasiswa WHERE nama LIKE :name ORDER BY nama ASC";
$params = [':name' => '%' . $name . '%'];
return $this->db->fetchAll($sql, $params);
} catch (Exception $e) {
error_log("Search mahasiswa failed: " . $e->getMessage());
throw new Exception("Gagal mencari data mahasiswa");
}
}
// UPDATE - Update data mahasiswa
public function update($id, $data) {
try {
// Validasi data
$this->validateMahasiswaData($data);
$sql = "UPDATE mahasiswa SET
nim = :nim, nama = :nama, email = :email,
jurusan = :jurusan, angkatan = :angkatan, alamat = :alamat
WHERE id = :id";
$params = [
':id' => $id,
':nim' => $data['nim'],
':nama' => $data['nama'],
':email' => $data['email'],
':jurusan' => $data['jurusan'],
':angkatan' => $data['angkatan'],
':alamat' => $data['alamat'] ?? null
];
$stmt = $this->db->query($sql, $params);
return $stmt->rowCount() > 0;
} catch (Exception $e) {
error_log("Update mahasiswa failed: " . $e->getMessage());
throw new Exception("Gagal mengupdate data mahasiswa");
}
}
// DELETE - Hapus data mahasiswa
public function delete($id) {
try {
$sql = "DELETE FROM mahasiswa WHERE id = :id";
$stmt = $this->db->query($sql, [':id' => $id]);
return $stmt->rowCount() > 0;
} catch (Exception $e) {
error_log("Delete mahasiswa failed: " . $e->getMessage());
throw new Exception("Gagal menghapus data mahasiswa");
}
}
// Validasi data mahasiswa
private function validateMahasiswaData($data) {
if (empty($data['nim']) || empty($data['nama']) || empty($data['email'])) {
throw new InvalidArgumentException("NIM, Nama, dan Email wajib diisi");
}
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Format email tidak valid");
}
if (!is_numeric($data['angkatan']) || $data['angkatan'] < 2000) {
throw new InvalidArgumentException("Angkatan harus berupa tahun yang valid");
}
}
// Get statistics
public function getStatistics() {
try {
$sql = "SELECT
COUNT(*) as total_mahasiswa,
COUNT(CASE WHEN status = 'aktif' THEN 1 END) as aktif,
COUNT(CASE WHEN status = 'lulus' THEN 1 END) as lulus,
jurusan,
COUNT(*) as jumlah_per_jurusan
FROM mahasiswa
GROUP BY jurusan";
return $this->db->fetchAll($sql);
} catch (Exception $e) {
error_log("Get statistics failed: " . $e->getMessage());
throw new Exception("Gagal mengambil statistik");
}
}
}
// Usage example
try {
$db = new Database();
$mahasiswaManager = new MahasiswaManager($db);
// Tambah mahasiswa baru
$newMahasiswa = [
'nim' => '2023001006',
'nama' => 'Test User',
'email' => 'test@email.com',
'jurusan' => 'Informatika',
'angkatan' => 2023,
'alamat' => 'Test Address'
];
$id = $mahasiswaManager->create($newMahasiswa);
echo "Mahasiswa baru ditambahkan dengan ID: " . $id;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
-- SQL untuk membuat database lengkap
CREATE DATABASE IF NOT EXISTS db_mahasiswa CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE db_mahasiswa;
CREATE TABLE mahasiswa (
id INT AUTO_INCREMENT PRIMARY KEY,
nim VARCHAR(20) NOT NULL UNIQUE,
nama VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
jurusan ENUM('Informatika', 'Sistem Informasi', 'Teknik Komputer') NOT NULL,
angkatan YEAR NOT NULL,
alamat TEXT,
telepon VARCHAR(15),
status ENUM('aktif', 'cuti', 'lulus', 'dropout') DEFAULT 'aktif',
tanggal_daftar TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
tanggal_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Indexes untuk performa
CREATE INDEX idx_nama ON mahasiswa(nama);
CREATE INDEX idx_jurusan ON mahasiswa(jurusan);
CREATE INDEX idx_angkatan ON mahasiswa(angkatan);
CREATE INDEX idx_status ON mahasiswa(status);
-- Sample data
INSERT INTO mahasiswa (nim, nama, email, jurusan, angkatan, alamat, telepon) VALUES
('2023001001', 'Ahmad Muyassar Ibrahim', 'ahmad.muyassar@email.com', 'Informatika', 2023, 'Jl. Veteran No. 123, Makassar', '081234567890'),
('2023002001', 'Siti Nurhaliza Putri', 'siti.nurhaliza@email.com', 'Sistem Informasi', 2023, 'Jl. Sudirman No. 456, Jakarta', '081234567891'),
('2022001001', 'Budi Santoso', 'budi.santoso@email.com', 'Informatika', 2022, 'Jl. Thamrin No. 789, Surabaya', '081234567892'),
('2022002001', 'Lisa Andriani', 'lisa.andriani@email.com', 'Sistem Informasi', 2022, 'Jl. Gatot Subroto No. 321, Bandung', '081234567893'),
('2021001001', 'Rudi Hartono', 'rudi.hartono@email.com', 'Teknik Komputer', 2021, 'Jl. Ahmad Yani No. 654, Yogyakarta', '081234567894');
<?php
// api/mahasiswa.php - RESTful API endpoint
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type');
require_once '../includes/Database.php';
require_once '../includes/MahasiswaManager.php';
try {
$db = new Database();
$mahasiswaManager = new MahasiswaManager($db);
$method = $_SERVER['REQUEST_METHOD'];
$input = json_decode(file_get_contents('php://input'), true);
switch ($method) {
case 'GET':
if (isset($_GET['id'])) {
// Get single mahasiswa
$mahasiswa = $mahasiswaManager->getById($_GET['id']);
echo json_encode(['success' => true, 'data' => $mahasiswa]);
} elseif (isset($_GET['search'])) {
// Search mahasiswa
$results = $mahasiswaManager->searchByName($_GET['search']);
echo json_encode(['success' => true, 'data' => $results]);
} else {
// Get all mahasiswa with pagination
$limit = $_GET['limit'] ?? 10;
$offset = $_GET['offset'] ?? 0;
$mahasiswa = $mahasiswaManager->getAll($limit, $offset);
echo json_encode(['success' => true, 'data' => $mahasiswa]);
}
break;
case 'POST':
// Create new mahasiswa
$id = $mahasiswaManager->create($input);
echo json_encode(['success' => true, 'id' => $id, 'message' => 'Mahasiswa berhasil ditambahkan']);
break;
case 'PUT':
// Update mahasiswa
if (!isset($_GET['id'])) {
throw new Exception('ID mahasiswa diperlukan untuk update');
}
$updated = $mahasiswaManager->update($_GET['id'], $input);
if ($updated) {
echo json_encode(['success' => true, 'message' => 'Mahasiswa berhasil diupdate']);
} else {
echo json_encode(['success' => false, 'message' => 'Data tidak ditemukan']);
}
break;
case 'DELETE':
// Delete mahasiswa
if (!isset($_GET['id'])) {
throw new Exception('ID mahasiswa diperlukan untuk delete');
}
$deleted = $mahasiswaManager->delete($_GET['id']);
if ($deleted) {
echo json_encode(['success' => true, 'message' => 'Mahasiswa berhasil dihapus']);
} else {
echo json_encode(['success' => false, 'message' => 'Data tidak ditemukan']);
}
break;
default:
throw new Exception('Method tidak didukung');
}
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
?>