📡 You're offline — showing cached content
New version available!
Quick Access
PHP Intermediate

PHP PDO: Prepared Statements and Transaction Handling

Complete PHP PDO guide — connecting to databases, prepared statements, named parameters, transactions with rollback, and lastInsertId.

EzyCoders Admin December 14, 2025 11 min read 0 views
PHP PDO Prepared Statements Transactions
Share: Twitter LinkedIn WhatsApp

PHP PDO — The Right Way to Use Databases

PDO (PHP Data Objects) provides a consistent database abstraction layer that works with MySQL, PostgreSQL, SQLite and more. Every PHP developer must know how to use prepared statements and transactions correctly.

<?php
// Connecting to MySQL
$pdo = new PDO(
    'mysql:host=localhost;dbname=ezycoders;charset=utf8mb4',
    'db_user',
    'db_pass',
    [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,   // throw on error
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,         // return arrays
        PDO::ATTR_EMULATE_PREPARES   => false,                    // real prepared stmts
    ]
);

Prepared Statements

<?php
// Positional parameters
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND active = ?');
$stmt->execute([$email, 1]);
$user = $stmt->fetch();

// Named parameters
$stmt = $pdo->prepare('SELECT * FROM users WHERE role = :role AND created_at > :since');
$stmt->execute(['role' => 'admin', 'since' => '2026-01-01']);
$admins = $stmt->fetchAll();

// Insert and get new ID
$stmt = $pdo->prepare('INSERT INTO posts (title, content, user_id) VALUES (?,?,?)');
$stmt->execute([$title, $content, $userId]);
$newId = (int) $pdo->lastInsertId();

// Update with row count check
$stmt = $pdo->prepare('UPDATE users SET name = ? WHERE id = ?');
$stmt->execute([$name, $id]);
if ($stmt->rowCount() === 0) throw new NotFoundException('User not found');

Transactions

<?php
function transferMoney(PDO $pdo, int $fromId, int $toId, float $amount): void {
    $pdo->beginTransaction();
    try {
        $stmt = $pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ? AND balance >= ?');
        $stmt->execute([$amount, $fromId, $amount]);
        if ($stmt->rowCount() === 0) {
            throw new RuntimeException('Insufficient balance');
        }

        $pdo->prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?')
            ->execute([$amount, $toId]);

        $pdo->prepare('INSERT INTO transactions (from_id, to_id, amount) VALUES (?,?,?)')
            ->execute([$fromId, $toId, $amount]);

        $pdo->commit();
    } catch (\Throwable $e) {
        $pdo->rollBack();
        throw $e;
    }
}

try {
    transferMoney($pdo, 1, 2, 5000.00);
    echo "Transfer complete!";
} catch (RuntimeException $e) {
    echo "Transfer failed: " . $e->getMessage();
}

Q: What does PDO::ATTR_EMULATE_PREPARES => false do?

By default, PDO emulates prepared statements by interpolating parameters client-side. Setting this to false tells PDO to use true prepared statements on the database server. True prepared statements are slightly more secure and fix edge cases where type coercion behaves unexpectedly with the emulated mode.

EzyCoders Admin
Written by
EzyCoders Admin

Team Lead and Full-Stack Developer with experience in PHP, JavaScript, SQL, DSA, and System Design. Passionate about software engineering, scalable web technologies, and helping developers prepare for coding interviews and tech careers through practical tutorials and professional guidance.

Comments (0)

No comments yet. Be the first!

Leave a Comment