Setiap interaksi dengan database diawali satu langkah yang sama: membuka koneksi dengan new PDO(...). Constructor ini menerima string alamat bernama DSN (Data Source Name), lalu nama pengguna dan kata sandi bila database membutuhkannya. Kesalahan pada langkah ini — salah ketik nama driver, host yang tidak aktif, nama database yang keliru — adalah error pertama yang hampir semua pengembang PHP alami. Pada chapter ini kita bedah anatomi DSN untuk SQLite, MySQL, dan PostgreSQL, menyetel opsi koneksi lewat array, menangani kegagalan dengan try/catch, lalu menutup koneksi dengan benar.

Anatomi DSN #

Format umum DSN adalah namaDriver:opsi=nilai;opsi=nilai — nama driver diikuti titik dua, kemudian opsi-opsi yang dipisahkan titik koma. Setiap driver menentukan sendiri opsi yang dimengertinya:

DriverContoh DSNKeterangan
sqlitesqlite::memory:database di memori, hilang saat skrip selesai
sqlitesqlite:/path/ke/toko.sqlitedatabase dalam berkas
mysqlmysql:host=127.0.0.1;port=3306;dbname=toko;charset=utf8mb4host, port, database, charset
pgsqlpgsql:host=localhost;port=5432;dbname=tokohost, port, database

SQLite adalah kasus paling sederhana: tidak ada server yang dilibatkan, jadi DSN cukup menunjuk berkas database (atau :memory: untuk memori), dan nama pengguna serta kata sandi diabaikan. MySQL dan PostgreSQL bekerja lewat jaringan, sehingga DSN harus menyebut alamat server dan nama database; kredensial dikirim sebagai argumen kedua dan ketiga constructor. Charset utf8mb4 pada DSN MySQL penting agar data teks Unicode tersimpan utuh — kebiasaan yang sebaiknya selalu dibawa.

Membuka dan Menutup Koneksi #

Contoh paling ringkas: koneksi SQLite di memori tanpa opsi apa pun. Atribut koneksi dapat dibaca kembali lewat getAttribute() untuk memastikan kita terhubung ke database yang benar:

php
<?php
$pdo = new PDO("sqlite::memory:");

echo "Driver        : " . $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) . "\n";
echo "Versi server  : " . $pdo->getAttribute(PDO::ATTR_SERVER_VERSION) . "\n";

$pdo = null; // melepas objek sekaligus menutup koneksi
echo "Koneksi       : ditutup\n";

Output yang Dihasilkan:

text
Driver        : sqlite
Versi server  : 3.45.2
Koneksi       : ditutup

Tiga hal terjadi di contoh tersebut:

  1. new PDO("sqlite::memory:"): PHP mencari driver bernama sqlite di antara driver yang aktif, lalu membuka database baru di memori.
  2. getAttribute(): ATTR_DRIVER_NAME mengembalikan nama driver yang dipakai koneksi, dan ATTR_SERVER_VERSION melaporkan versi engine database — berguna untuk mencatat lingkungan atau menyesuaikan fitur.
  3. $pdo = null;: koneksi ditutup dengan melepas objek PDO. Pada skrip CLI, koneksi juga otomatis tertutup saat skrip selesai; penetapan null secara eksplisit hanya perlu bila kita ingin membebaskannya lebih awal (misalnya sebelum menghapus berkas database, seperti contoh di akhir chapter).

Menyetel Opsi Koneksi #

Constructor PDO menerima array opsi sebagai parameter keempat. Dua opsi yang sebaiknya selalu ada: mode error exception dan fetch mode asosiatif — sama dengan pasangan setAttribute() yang kita pakai pada chapter-chapter sebelumnya, hanya ditulis sekali di awal:

php
<?php
$opsi = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

// SQLite tidak memakai nama pengguna dan kata sandi: kirim null
$pdo = new PDO("sqlite::memory:", null, null, $opsi);

$pdo->exec("CREATE TABLE kota (nama TEXT)");
$pdo->exec("INSERT INTO kota (nama) VALUES ('Bandung')");

$kota = $pdo->query("SELECT nama FROM kota")->fetch();
echo "Kota pertama: {$kota['nama']}\n";

Output yang Dihasilkan:

text
Kota pertama: Bandung

Array $opsi memetakan konstanta atribut ke nilainya; karena SQLite tidak mengenal kredensial, parameter kedua dan ketiga diisi null. Hasilnya langsung terasa pada baris terakhir: fetch() mengembalikan array asosiatif tanpa perlu menyebut PDO::FETCH_ASSOC di tiap panggilan. Opsi-opsi lain yang sering dipakai:

OpsiKegunaan
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTIONkesalahan SQL melempar PDOException
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOChasil fetch berupa array asosiatif
PDO::ATTR_PERSISTENT => truekoneksi dipakai ulang antarpermintaan

Menangani Kegagalan Koneksi #

Constructor new PDO() melempar PDOException ketika koneksi gagal dibuka, sehingga kegagalan dapat ditangkap dengan try/catch. Kasus paling ringkas untuk diuji: DSN dengan nama driver yang salah ketik:

php
<?php
$dsn = "sqlitex::memory:"; // salah ketik: seharusnya "sqlite"

try {
    $pdo = new PDO($dsn);
    echo "Koneksi berhasil\n";
} catch (PDOException $e) {
    echo "Koneksi gagal: " . $e->getMessage() . "\n";
}

Output yang Dihasilkan:

text
Koneksi gagal: could not find driver

Pesan could not find driver berarti PHP tidak mengenal nama driver di awal DSN — baik karena salah ketik, maupun karena ekstensi drivernya memang tidak aktif (periksa dengan PDO::getAvailableDrivers() seperti pada chapter Database Drivers ). Untuk MySQL dengan server sungguhan, polanya sama persis hanya DSN dan kredensial yang berbeda:

php
<?php
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=toko;charset=utf8mb4";

try {
    $pdo = new PDO($dsn, "budi", "YOUR_DATABASE_PASSWORD", [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
    echo "Koneksi MySQL berhasil\n";
} catch (PDOException $e) {
    echo "Koneksi gagal: " . $e->getMessage() . "\n";
}

Contoh di atas memerlukan server MySQL yang sedang berjalan, sehingga tidak dieksekusi pada build course ini (tidak ada server database terpasang). Dua pesan kegagalan yang paling sering muncul di dunia nyata: could not find driver artinya ekstensi pdo_mysql belum aktif di php.ini, sedangkan Connection refused artinya driver aktif tetapi tidak ada server yang mendengarkan di host dan port tersebut. Pesan Access denied berarti kredensial salah — tiga pesan ini menggiring ke tiga perbaikan yang berbeda, jadi biasakan membaca isinya sebelum menebak.

Database SQLite dalam Berkas #

Selain :memory:, driver sqlite dapat menunjuk berkas di disk. Data bertahan antar-eksekusi skrip — perilaku yang lebih dekat dengan database sungguhan:

php
<?php
$berkas = "/tmp/toko-latihan.sqlite";
if (file_exists($berkas)) {
    unlink($berkas); // mulai dari berkas bersih agar contoh selalu konsisten
}

$pdo = new PDO("sqlite:" . $berkas);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec("CREATE TABLE pengaturan (kunci TEXT PRIMARY KEY, nilai TEXT)");
$pdo->exec("INSERT INTO pengaturan (kunci, nilai) VALUES ('nama_toko', 'Toko Budi')");

$nama = $pdo->query("SELECT nilai FROM pengaturan WHERE kunci = 'nama_toko'")->fetchColumn();
echo "Nama toko: $nama\n";

$pdo = null;      // tutup koneksi sebelum berkas dihapus
unlink($berkas);  // bersihkan berkas latihan
echo "Berkas database latihan dihapus\n";

Output yang Dihasilkan:

text
Nama toko: Toko Budi
Berkas database latihan dihapus

DSN dibentuk dengan menggabungkan "sqlite:" dan path berkas, lalu tabel dibuat dan dibaca seperti biasa. Koneksi ditutup dengan $pdo = null sebelum unlink() — pada sistem operasi tertentu, berkas yang masih terbuka oleh proses tidak dapat dihapus. Contoh ini juga sengaja menghapus berkas di awal dan di akhir agar hasilnya selalu konsisten setiap dijalankan.

Ringkasan #

Koneksi PDO dibuka dengan new PDO($dsn, $user, $password, $opsi): DSN menentukan driver dan alamatnya, array opsi menyetel perilaku (mode error exception dan fetch asosiatif adalah pasangan wajib), dan kegagalan ditangkap lewat PDOException. SQLite unik karena DSN-nya berupa path berkas atau :memory:, dan driver-nya membuat berkas baru secara diam-diam bila path tidak ada. Dengan koneksi yang sehat di tangan, kita siap membahas cara yang benar mengirim data eksternal ke database: prepared statements pada chapter berikutnya.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh.php

Unduh berkas
php
<?php
/**
 * contoh.php - rangkuman Chapter PDO Connections.
 *
 * Membuka koneksi SQLite memori dengan opsi, membaca atribut koneksi,
 * menangani kegagalan DSN, lalu menutup koneksi secara eksplisit.
 */

$pdo = new PDO("sqlite::memory:", null, null, [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

echo "Driver       : " . $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) . "\n";
echo "Versi server : " . $pdo->getAttribute(PDO::ATTR_SERVER_VERSION) . "\n";

// Uji koneksi dengan query sederhana
$pdo->exec("CREATE TABLE status (pesan TEXT)");
$pdo->exec("INSERT INTO status (pesan) VALUES ('koneksi sehat')");
echo "Hasil uji    : " . $pdo->query("SELECT pesan FROM status")->fetchColumn() . "\n";

// DSN yang salah menimbulkan PDOException yang bisa ditangkap
try {
    new PDO("sqlitex::memory:");
} catch (PDOException $e) {
    echo "DSN salah    : " . $e->getMessage() . "\n";
}

// Menutup koneksi secara eksplisit
$pdo = null;
echo "Koneksi      : ditutup\n";