PHP MySQL With PDO
PHP MySQL access with PDO (PHP Data Objects) is the recommended way to work with databases in plain PHP. PDO supports MySQL, PostgreSQL, SQLite and more with one API, and its prepared statements protect you from SQL injection.
Connecting to MySQL With PDO
Create a PDO object with a DSN string, username and password. Set the error mode to exceptions and default fetch mode to associative arrays.
<?php
$dsn = 'mysql:host=127.0.0.1;dbname=shop;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', 'secret', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
echo "Connected";Connected
Prepared Statements Prevent SQL Injection
Never put user input directly into SQL. Use placeholders and pass values separately; the database treats them as data, never as SQL code.
<?php
$email = $_GET['email'] ?? 'sara@example.com';
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
echo $user ? "Found {$user['name']}" : "No user";Found Sara
Insert, Update and Delete
<?php
$stmt = $pdo->prepare('INSERT INTO products (name, price) VALUES (?, ?)');
$stmt->execute(['Green Tea', 4.5]);
echo "New ID: " . $pdo->lastInsertId() . "\n";
$stmt = $pdo->prepare('UPDATE products SET price = ? WHERE id = ?');
$stmt->execute([4.99, 12]);
echo "Updated rows: " . $stmt->rowCount() . "\n";
$pdo->prepare('DELETE FROM products WHERE id = ?')->execute([12]);
echo "Deleted";New ID: 12 Updated rows: 1 Deleted
Fetching Many Rows
<?php
$stmt = $pdo->query('SELECT name, price FROM products ORDER BY price LIMIT 3');
foreach ($stmt->fetchAll() as $row) {
printf("%-10s %6.2f\n", $row['name'], $row['price']);
}Salt 0.99 Rice 3.20 Green Tea 4.50
Transactions
A transaction makes several queries succeed or fail together, for example moving money between accounts.
<?php
try {
$pdo->beginTransaction();
$pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?')->execute([100, 1]);
$pdo->prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?')->execute([100, 2]);
$pdo->commit();
echo "Transfer complete";
} catch (Throwable $e) {
$pdo->rollBack();
echo "Transfer failed";
}Transfer complete
Frequently asked questions
Should I use PDO or MySQLi?
PDO is usually the better choice: it supports many databases, has named placeholders and a cleaner API. MySQLi works only with MySQL.
How do prepared statements prevent SQL injection?
The SQL and the values are sent separately, so the database never interprets user input as SQL commands.
Where should I store database passwords?
In environment variables or a config file outside the public web root, never hard-coded in files committed to Git.