PHP Data Objects (PDO)

Secure & Portable Database Access

Oleh: Ahmad Muyassar, S.Kom.,M.Cs

Agenda Pembelajaran

01. Pengenalan PDO
02. Koneksi Database
03. Prepared Statements
04. Fetching Data
05. Keamanan (SQL Injection)
01

Pengenalan PDO

Mengapa Menggunakan PDO?

Apa itu PDO?

PDO (PHP Data Objects) adalah extension PHP yang menyediakan antarmuka (interface) yang ringan dan konsisten untuk mengakses database.

PDO tidak hanya untuk MySQL, tapi mendukung banyak database driver lainnya.

PDO vs MySQLi

Fitur PDO MySQLi
Database Support 12+ (MySQL, PostgreSQL, SQLite, dll) MySQL Only
Paradigm OOP Only OOP & Procedural
Named Parameters Yes (:id) No (?)

Keunggulan Utama PDO

02

Koneksi Database

Menghubungkan PHP dengan MySQL

Data Source Name (DSN)

Koneksi PDO membutuhkan DSN, yaitu string yang berisi informasi driver, host, dan nama database.


$dsn = "mysql:host=localhost;dbname=sekolah;charset=utf8mb4";
            

Membuat Koneksi

Instansiasi class PDO dengan DSN, Username, dan Password.


$host = 'localhost';
$db   = 'sekolah';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";

try {
    $pdo = new PDO($dsn, $user, $pass);
    echo "Koneksi Sukses!";
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
            

PDO Options

Kita bisa mengatur opsi tambahan saat koneksi, misalnya untuk Error Mode dan Fetch Mode default.


$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

$pdo = new PDO($dsn, $user, $pass, $options);
            

Pentingnya ERRMODE_EXCEPTION

Secara default, PDO mungkin hanya diam saat error (Silent). Selalu set ERRMODE_EXCEPTION agar PDO melempar Exception saat query gagal, sehingga bisa ditangkap dengan try-catch.

03

Prepared Statements

Jantung Keamanan Database

Masalah Query Biasa

Menggabungkan string query dengan input user secara langsung sangat berbahaya.


// BAHAYA! JANGAN DITIRU
$sql = "SELECT * FROM users WHERE email = '$email'";
$pdo->query($sql);
            

Rentan SQL Injection!

Konsep Prepared Statements

Prepared Statements memisahkan Query Template dan Data.

  1. Prepare: Database menerima template query (dengan placeholder).
  2. Bind: PHP mengirimkan data untuk mengisi placeholder.
  3. Execute: Database menjalankan query.

Placeholder: Named Parameters

Menggunakan titik dua diikuti nama (misal :email).


$sql = "SELECT * FROM users WHERE email = :email AND status = :status";
$stmt = $pdo->prepare($sql);
$stmt->execute(['email' => $email, 'status' => 'active']);
            

Placeholder: Positional Parameters

Menggunakan tanda tanya ?.


$sql = "SELECT * FROM users WHERE email = ? AND status = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$email, 'active']);
            

Binding Manual (bindValue)

Untuk kontrol lebih detail (misal tipe data).


$stmt = $pdo->prepare("SELECT * FROM users WHERE age > :age");
$stmt->bindValue(':age', 18, PDO::PARAM_INT);
$stmt->execute();
            
04

Fetching Data

Mengambil Hasil Query

fetch() vs fetchAll()

Fetch Modes: PDO::FETCH_ASSOC

Mengembalikan array asosiatif (key = nama kolom).


$stmt = $pdo->query("SELECT name, email FROM users");
$user = $stmt->fetch(PDO::FETCH_ASSOC);

echo $user['name']; // Ahmad
            

Fetch Modes: PDO::FETCH_OBJ

Mengembalikan anonymous object.


$user = $stmt->fetch(PDO::FETCH_OBJ);

echo $user->name; // Ahmad
            

Fetch Modes: PDO::FETCH_CLASS

Mapping langsung ke Class yang sudah kita buat.


class User { public $name; }

$stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
$user = $stmt->fetch();

echo $user->name; // Ahmad (Property dari class User)
            

Iterasi Data (Looping)

Cara terbaik mengambil banyak data adalah dengan while loop dan fetch().


$stmt = $pdo->query("SELECT * FROM products");

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['product_name'] . "
"; }

Menghitung Jumlah Baris (rowCount)

Untuk query INSERT, UPDATE, DELETE, gunakan rowCount() untuk melihat baris yang terdampak.


$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute(['id' => 1]);

echo $stmt->rowCount() . " user dihapus.";
            

Last Insert ID

Mendapatkan ID dari data yang baru saja di-insert (Auto Increment).


$pdo->exec("INSERT INTO users (name) VALUES ('Budi')");
$id = $pdo->lastInsertId();

echo "User baru memiliki ID: " . $id;
            
05

CRUD Operations

Create, Read, Update, Delete

CREATE (Insert)


$sql = "INSERT INTO users (name, email, password) VALUES (:name, :email, :pass)";
$stmt = $pdo->prepare($sql);

$data = [
    'name' => 'Ahmad',
    'email' => 'ahmad@test.com',
    'pass' => password_hash('rahasia', PASSWORD_DEFAULT)
];

$stmt->execute($data);
            

READ (Select)


$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => 1]);
$user = $stmt->fetch();

if ($user) {
    echo "Halo, " . $user['name'];
} else {
    echo "User tidak ditemukan.";
}
            

UPDATE


$sql = "UPDATE users SET name = :name WHERE id = :id";
$stmt = $pdo->prepare($sql);

$stmt->execute([
    'name' => 'Ahmad Update',
    'id' => 1
]);
            

DELETE


$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute(['id' => 1]);
            
06

Transactions

Menjaga Integritas Data

Apa itu Transaction?

Transaction memastikan sekumpulan query dijalankan secara Atomic (Semua sukses, atau semua gagal).

Contoh: Transfer bank (Kurangi saldo A, Tambah saldo B).

Implementasi Transaction


try {
    $pdo->beginTransaction();

    // Query 1: Potong saldo pengirim
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");

    // Query 2: Tambah saldo penerima
    $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");

    $pdo->commit(); // Simpan perubahan permanen
} catch (Exception $e) {
    $pdo->rollBack(); // Batalkan semua perubahan jika ada error
    echo "Transfer Gagal: " . $e->getMessage();
}
            
07

Security

Mencegah SQL Injection

SQL Injection Explained

Serangan di mana hacker menyisipkan perintah SQL berbahaya melalui input form.

Contoh input: ' OR '1'='1

Query menjadi: SELECT * FROM users WHERE email = '' OR '1'='1' (Selalu True!)

Mengapa Prepared Statement Aman?

Karena database memperlakukan input user sebagai DATA MURNI, bukan sebagai kode SQL yang bisa dieksekusi.

Meskipun input berisi ' OR '1'='1, database hanya akan mencari user dengan email persis seperti string aneh tersebut.

Tips Keamanan Lainnya

Debugging PDO

Gunakan debugDumpParams() untuk melihat query final yang dikirim (termasuk parameter).


$stmt->execute(['id' => 1]);
$stmt->debugDumpParams();
            

Kesimpulan

Terima Kasih

Selamat Belajar Database!

1 / 40