If you're working with a PHP website that needs to store and retrieve data, you'll need to connect it to a MySQL database. But which method should you use? PDO or MySQLi? π€
In this step-by-step guide, weβll cover:
β
Differences between PDO and MySQLi
β
How to connect PHP to MySQL using both methods
β
How to prevent SQL injection
β
Building a mini-project
Letβs dive in! π
π― PDO vs. MySQLi: Which One Should You Use?
Both PDO and MySQLi allow PHP to interact with MySQL, but they have key differences.
Feature | PDO | MySQLi |
---|---|---|
Supports MySQL? | β Yes | β Yes |
Supports Other Databases? | β Yes (PostgreSQL, SQLite, etc.) | β No (Only MySQL) |
Object-Oriented? | β Yes | β Yes |
Prepared Statements? | β Yes | β Yes |
More Secure? | β Yes | β Yes |
Fetching Multiple Data Types? | β Yes | β Limited |
π Recommendation: Use PDO if you need flexibility and want the ability to switch databases in the future. Use MySQLi if you're only working with MySQL and want a slightly faster performance.
1οΈβ£ Connecting to MySQL Using PDO
db_pdo.php (Database Connection with PDO)
<?php
$host = "localhost";
$dbname = "zeroexp_dev";
$username = "root";
$password = "";
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully (PDO)";
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
?>
π₯ Whatβs happening?
new PDO(...)
creates a connection to MySQL.setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
enables error handling.- If something goes wrong, the script will catch the error and display a message.
2οΈβ£ Connecting to MySQL Using MySQLi
db_mysqli.php (Database Connection with MySQLi)
<?php
$host = "localhost";
$dbname = "zeroexp_dev";
$username = "root";
$password = "";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully (MySQLi)";
?>
π₯ Whatβs happening?
new mysqli(...)
connects to MySQL.connect_error
checks if the connection failed.- If something goes wrong, an error message is displayed.
3οΈβ£ Performing CRUD Operations (PDO vs. MySQLi)
1οΈβ£ Insert Data
Using PDO
<?php
require "db_pdo.php";
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute(["Zero Dev", "contact@zeroexp.dev"]);
echo "User added!";
?>
Using MySQLi
<?php
require "db_mysqli.php";
$name = "Zero Dev";
$email = "contact@zeroexp.dev";
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
$stmt->execute();
echo "User added!";
?>
π₯ Why Use Prepared Statements?
β
Prevents SQL Injection
β
Ensures data safety
β
Allows parameter binding
2οΈβ£ Fetch Data
Using PDO
<?php
require "db_pdo.php";
$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($users as $user) {
echo "{$user['id']}: {$user['name']} ({$user['email']}) <br>";
}
?>
Using MySQLi
<?php
require "db_mysqli.php";
$result = $conn->query("SELECT * FROM users");
while ($user = $result->fetch_assoc()) {
echo "{$user['id']}: {$user['name']} ({$user['email']}) <br>";
}
?>
π₯ Whatβs Happening?
- PDO: Uses
fetchAll(PDO::FETCH_ASSOC)
to get all rows as an array. - MySQLi: Uses
fetch_assoc()
inside a loop to retrieve one row at a time.
3οΈβ£ Update Data
Using PDO
<?php
require "db_pdo.php";
$stmt = $pdo->prepare("UPDATE users SET email = ? WHERE name = ?");
$stmt->execute(["newemail@zeroexp.dev", "Zero Dev"]);
echo "User updated!";
?>
Using MySQLi
<?php
require "db_mysqli.php";
$new_email = "newemail@zeroexp.dev";
$name = "Zero Dev";
$stmt = $conn->prepare("UPDATE users SET email = ? WHERE name = ?");
$stmt->bind_param("ss", $new_email, $name);
$stmt->execute();
echo "User updated!";
?>
π₯ Why Use Prepared Statements?
- Prevents SQL injection
- Ensures safe database updates
4οΈβ£ Delete Data
Using PDO
<?php
require "db_pdo.php";
$stmt = $pdo->prepare("DELETE FROM users WHERE name = ?");
$stmt->execute(["Zero Dev"]);
echo "User deleted!";
?>
Using MySQLi
<?php
require "db_mysqli.php";
$name = "Zero Dev";
$stmt = $conn->prepare("DELETE FROM users WHERE name = ?");
$stmt->bind_param("s", $name);
$stmt->execute();
echo "User deleted!";
?>
π₯ Whatβs Happening?
- Deletes a user based on
name
. - Uses prepared statements to prevent SQL injection.
π― Mini Project: Simple User Management System
Letβs put everything together into a mini CRUD app.
1οΈβ£ user_list.php (Display Users)
<?php
require "db_pdo.php";
$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($users as $user) {
echo "{$user['id']}: {$user['name']} ({$user['email']})
<a href='edit_user.php?id={$user['id']}'>Edit</a> |
<a href='delete_user.php?id={$user['id']}'>Delete</a><br>";
}
echo "<a href='add_user.php'>Add New User</a>";
?>
2οΈβ£ add_user.php (Add User Form)
<form method="post" action="insert.php">
Name: <input type="text" name="name"><br>
Email: <input type="email" name="email"><br>
<input type="submit" value="Add User">
</form>
3οΈβ£ insert.php (Insert New User)
<?php
require "db_pdo.php";
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$_POST['name'], $_POST['email']]);
header("Location: user_list.php");
?>
π₯ Boom! You now have a fully functional user management system! π
π Final Thoughts
Now you know:
β
How to connect PHP to MySQL using PDO and MySQLi
β
How to perform CRUD operations
β
How to prevent SQL injection
β
How to build a mini CRUD app
π Next: Preventing SQL Injection with Prepared Statement in PHP
Happy coding! ππ