Php Using Pdo And Mysqli Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    8 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of PHP Using PDO and MySQLi


PHP Using PDO and MySQLi

PHP Data Objects (PDO) and MySQL Improved Extension (MySQLi) are two popular database access layers used by PHP to interact with MySQL databases. Both extensions offer methods for executing SQL queries, managing transactions, and handling prepared statements. However, they have different philosophies and capabilities:

Overview and Comparison

  1. Purpose:

    • Both PDO and MySQLi provide a robust way to connect to and manipulate MySQL databases.
  2. Driver-Based Approach:

    • PDO supports multiple database drivers (not limited to MySQL), allowing developers to easily switch between different database systems without changing the application code.
    • MySQLi is specifically designed for MySQL and includes enhanced features and optimizations tailored for MySQL.
  3. Object-Oriented and Procedural Interfaces:

    • PDO uses an object-oriented interface exclusively.
    • MySQLi offers both an object-oriented and procedural interface, providing flexibility depending on individual coding styles.
  4. Prepared Statements Support:

    • Both PDO and MySQLi support prepared statements, which help prevent SQL injection attacks and improve performance by pre-compiling SQL commands.
  5. API Features:

    • PDO emphasizes portability and provides a unified API across various database types, which can be advantageous in large applications that may need to run against different database backends.
    • MySQLi focuses on offering advanced features specific to MySQL, such as enhanced error reporting, multiple statement execution, and improved performance through persistent connections.

Using PDO

Connecting to MySQL Database using PDO

try {
    $dsn = 'mysql:host=localhost;dbname=yourdatabase;charset=utf8mb4';
    $options = [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ];
    $pdo = new PDO($dsn, 'yourusername', 'yourpassword', $options);
} catch (\PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

// Alternatively, without exception handling:
$pdo = new PDO($dsn, 'yourusername', 'yourpassword');
  • DSN (Data Source Name):

    • Specifies the host, database name, and optionally other parameters like the character set used.
    • E.g., mysql:host=localhost;dbname=testdb;charset=utf8mb4
  • Options Array:

    • PDO::ATTR_ERRMODE: Set to PDO::ERRMODE_EXCEPTION to force PDO to throw exceptions upon encountering errors.
    • PDO::ATTR_DEFAULT_FETCH_MODE: Determines the default fetch mode, e.g., PDO::FETCH_ASSOC to return results as an associative array.
    • PDO::ATTR_EMULATE_PREPARES: Set to false to utilize real prepared statements rather than emulated ones, enhancing security and performance.

Executing SQL Statements with PDO

Example: Selecting Data
$stmt = $pdo->query("SELECT * FROM users");

while ($row = $stmt->fetch()) {
    echo $row['name'] . '<br>';
}
Example: Inserting Data
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$newUser = ['John Doe', 'john@example.com'];
$stmt->execute($newUser);
  • Query Method:

    • Ideal for executing non-prepared statements that do not require any input from the user.
  • Prepare Method:

    • Use when dealing with SQL queries containing dynamic data to prevent SQL injection.
    • Utilizes placeholders (?) in the query string which are then replaced by actual values at runtime.
Binding Parameters
$stmt = $pdo->prepare("SELECT * FROM users WHERE age > :age LIMIT :limit");
$stmt->bindValue(':age', 18, PDO::PARAM_INT);
$stmt->bindValue(':limit', 10, PDO::PARAM_INT);
$stmt->execute();

while ($row = $stmt->fetch()) {
    echo $row['name'] . '<br>';
}
  • bindValue Method:
    • Binds a value to a parameter in a prepared statement.
    • The third argument specifies the data type of the parameter.
Fetching Results
  • Fetch Methods:
    • fetch(PDO::FETCH_ASSOC): Returns a single row as an associative array.
    • fetchAll(PDO::FETCH_ASSOC): Retrieves all rows into an associative array.
    • fetchColumn(): Fetches a single column from the next row of a result set.

Transactions with PDO

try {
    $pdo->beginTransaction();

    $sql1 = 'INSERT INTO users (name, email) VALUES (?, ?)';
    $stmt1 = $pdo->prepare($sql1);
    $stmt1->execute(['Alice Johnson', 'alice@example.com']);

    $sql2 = 'UPDATE profiles SET bio = ? WHERE user_id = ?';
    $stmt2 = $pdo->prepare($sql2);
    $stmt2->execute(['New bio text here', $pdo->lastInsertId()]);

    $pdo->commit();
} catch (\Exception $e) {
    $pdo->rollBack();
    echo 'Transaction failed: ' . $e->getMessage();
}
  • beginTransaction Method:

    • Starts a transaction.
  • commit Method:

    • Commits the current transaction, making all changes permanent.
  • rollBack Method:

    • Rolls back the current transaction, undoing all changes made during the transaction.

Using MySQLi

Connecting to MySQL Database using MySQLi

Object-Oriented Interface:

$mysqli = new mysqli('localhost', 'yourusername', 'yourpassword', 'yourdatabase');

if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') '
        . $mysqli->connect_error);
}

Procedural Interface:

$mysqli = mysqli_connect('localhost', 'yourusername', 'yourpassword', 'yourdatabase');

if (!$mysqli) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
        . mysqli_connect_error());
}
  • Connection:
    • MySQLi accepts four parameters for establishing a connection: hostname, username, password, and database name.
    • In the procedural approach, $mysqli is a resource, whereas in the object-oriented approach, it is an instance of the mysqli class.

Executing SQL Statements with MySQLi

Object-Oriented Interface:

Example: Selecting Data
$result = $mysqli->query("SELECT * FROM users");

while ($row = $result->fetch_assoc()) {
    echo $row['name'] . '<br>';
}
Example: Inserting Data
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");

$name = "Bob Smith";
$email = "bob@example.com";

$stmt->bind_param("ss", $name, $email); // "ss" indicates two strings
$stmt->execute();
  • query Method:

    • Executes a query and retrieves the results.
    • Suitable for non-prepared statements.
  • prepare Method:

    • Used for creating a prepared statement with placeholders.
    • Enforces secure data handling.

Binding Parameters:

$stmt->bind_param("is", $age, $name); // "is" indicates integer and string
  • bind_param Method:
    • Binds variables to the prepared statement as parameters.
    • The first argument is a string specifying the types of each parameter: i for integer, d for double, s for string, and b for blob.

Fetching Results:

  • fetch_assoc Method:
    • Retrieves a result row as an associative array.

Procedural Interface:

Example: Inserting Data
$stmt = mysqli_prepare($mysqli, "INSERT INTO users (name, email) VALUES (?, ?)");

$name = "Charlie Brown";
$email = "charlie@example.com";

mysqli_stmt_bind_param($stmt, "ss", $name, $email);
mysqli_stmt_execute($stmt);

echo mysqli_stmt_affected_rows($stmt) . ' rows inserted.';
  • mysqli_prepare:

    • Creates a prepared statement for executing against the database.
  • mysqli_stmt_bind_param:

    • Binds variables to a prepared statement as parameters.
  • mysqli_stmt_execute:

    • Executes the prepared statement.
  • mysqli_stmt_affected_rows:

    • Returns the number of affected rows from the last executed statement.

Multiple Statement Execution with MySQLi (Not Available in PDO)

MySQLi allows running multiple queries within a single call:

if ($mysqli->multi_query($queries)) {
    do {
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_assoc()) {
                echo $row['name'] . "<br>";
            }
            $result->free();
        } else {
            printf("Error: %s\n", $mysqli->error);
        }

        if ($mysqli->more_results()) {
            printf("--------------------\n");
        }
    } while ($mysqli->next_result());
}
  • multi_query:

    • Executes multiple queries separated by semicolons.
  • store_result:

    • Transfers the result set from the last query to memory.
  • more_results and next_result:

    • Iterates through multiple result sets returned by multi_query.

Error Handling with MySQLi

Using Exceptions:

MySQLi does not natively support exceptions for error handling, but this behavior can be enabled using:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

try {
    $mysqli = new mysqli('localhost', 'nonexistent_user', '', 'test');
} catch (\mysqli_sql_exception $e) {
    echo 'Error connecting to database: ' . $e->getMessage();
}
  • mysqli_report:
    • Configures the MySQLi driver to report an error using exceptions.
    • Combines flags MYSQLI_REPORT_ERROR and MYSQLI_REPORT_STRICT to ensure all errors are reported as exceptions.

Traditional Error Handling:

if (!$mysqli = mysqli_connect('localhost', 'nonexistent_user', '', 'test')) {
    echo 'Connection error: ' . mysqli_connect_error();
}

$stmt = $mysqli->prepare("SELECT * FROM non_existent_table");
if (!$stmt) {
    echo 'Error preparing statement: ' . $mysqli->error;
}
  • error Message:
    • Retrieves the last error message string from the most recent function call that can succeed or fail.

Important Security Considerations

  1. SQL Injection Prevention:

    • Always use prepared statements with bound parameters instead of directly concatenating user inputs into SQL queries.
  2. Character Encoding:

    • Specify the character encoding in the DSN or explicitly after connecting using set_charset.
    • E.g., $pdo->exec("SET NAMES utf8mb4"); or $mysqli->set_charset("utf8mb4");
    • This ensures proper character encoding, preventing potential security issues and data corruption.
  3. Password Storage:

    • Never store plain passwords in your database.
    • Use strong hashing algorithms like bcrypt via PHP's password_hash and password_verify functions.

Conclusion

Both PDO and MySQLi are powerful tools for interacting with MySQL databases in PHP. The choice between them depends on specific project requirements and developer preferences:

  • PDO: Suitable for projects requiring multiple database support, with its portable and unified API.
  • MySQLi: Ideal for projects specifically targeting MySQL, leveraging enhanced MySQL-specific features.

Regardless of the chosen extension, always implement best practices in terms of security and performance to ensure the robustness of your application.


Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement PHP Using PDO and MySQLi

Complete Examples, Step by Step for Beginners: PHP Using PDO and MySQLi


Step 1: Setting Up Your Database

For both examples, let's assume you have a MySQL database named test_db and a table named users with the following structure:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
);

Step 2: Inserting Data

Using PDO:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

try {
    // Create a new PDO instance
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    // Set the PDO error mode to exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Prepare a statement
    $stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");

    // Bind parameters to statement variables
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':email', $email);

    // Set parameters
    $name = 'Alice';
    $email = 'alice@example.com';

    // Execute the prepared statement
    $stmt->execute();

    echo "New record created successfully";
} catch(PDOException $e) {
    die("ERROR: Could not execute $sql. " . $e->getMessage());
}

// Close connection
unset($pdo);
?>

Using MySQLi:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

// Create a new MySQLi connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($host, $username, $password, $dbname);

// Prepare a statement
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");

// Bind parameters to statement variables
$stmt->bind_param("ss", $name, $email);

// Set parameters
$name = 'Bob';
$email = 'bob@example.com';

// Execute the prepared statement
$stmt->execute();

echo "New record created successfully";

// Close connection
$stmt->close();
$mysqli->close();
?>

Step 3: Retrieving Data

Using PDO:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

try {
    // Create a new PDO instance
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    // Set the PDO error mode to exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Prepare a statement
    $stmt = $pdo->prepare("SELECT id, name, email FROM users");

    // Execute the statement
    $stmt->execute();

    // Fetch data as an associative array
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($result as $row) {
        echo "ID: " . htmlspecialchars($row['id']) . ", Name: " . htmlspecialchars($row['name']) . ", Email: " . htmlspecialchars($row['email']) . "<br>";
    }
} catch(PDOException $e) {
    die("ERROR: Could not execute $sql. " . $e->getMessage());
}

// Close connection
unset($pdo);
?>

Using MySQLi:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

// Create a new MySQLi connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($host, $username, $password, $dbname);

// Prepare a statement
$stmt = $mysqli->prepare("SELECT id, name, email FROM users");

// Execute the statement
$stmt->execute();

// Fetch data
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    echo "ID: " . htmlspecialchars($row['id']) . ", Name: " . htmlspecialchars($row['name']) . ", Email: " . htmlspecialchars($row['email']) . "<br>";
}

// Close connection
$stmt->close();
$mysqli->close();
?>

Step 4: Updating Data

Using PDO:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

try {
    // Create a new PDO instance
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    // Set the PDO error mode to exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Prepare a statement
    $stmt = $pdo->prepare("UPDATE users SET name = :name, email = :email WHERE id = :id");

    // Bind parameters to statement variables
    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':email', $email);
    $stmt->bindParam(':id', $id);

    // Set parameters
    $name = 'Alice Updated';
    $email = 'aliceupdated@example.com';
    $id = 1;

    // Execute the prepared statement
    $stmt->execute();

    echo "Record updated successfully";
} catch(PDOException $e) {
    die("ERROR: Could not execute $sql. " . $e->getMessage());
}

// Close connection
unset($pdo);
?>

Using MySQLi:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

// Create a new MySQLi connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli($host, $username, $password, $dbname);

// Prepare a statement
$stmt = $mysqli->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?");

// Bind parameters to statement variables
$stmt->bind_param("ssi", $name, $email, $id);

// Set parameters
$name = 'Bob Updated';
$email = 'bobupdated@example.com';
$id = 2;

// Execute the prepared statement
$stmt->execute();

echo "Record updated successfully";

// Close connection
$stmt->close();
$mysqli->close();
?>

Step 5: Deleting Data

Using PDO:

<?php
// Database configuration
$host = '127.0.0.1';
$dbname = 'test_db';
$username = 'root';
$password = '';

try {
    // Create a new PDO instance
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    // Set the PDO error mode to exception
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Prepare a statement
    $stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");

    // Bind parameters to statement variables
    $stmt->bindParam(':id', $id);

    // Set parameters
    $id = 1;

    // Execute the prepared statement
    $stmt->execute();

    echo "Record deleted successfully";
} catch(PDOException $e) {
    die("ERROR: Could not execute $sql. " . $e->getMessage());
}

// Close connection
unset($pdo);
?>

Using MySQLi:

Top 10 Interview Questions & Answers on PHP Using PDO and MySQLi

Top 10 Questions and Answers on PHP Using PDO and MySQLi

1. What is PDO in PHP?

2. What are the main differences between PDO and MySQLi?

Answer: Both PDO and MySQLi are extensions for PHP that allow database interaction, but they have some key differences:

  • Support for Multiple Databases: PDO supports multiple databases, making it more flexible, while MySQLi is specific to MySQL.
  • API Style: PDO provides an object-oriented and procedural interface, whereas MySQLi supports both object-oriented and procedural styles.
  • Prepared Statements: Both support prepared statements, but MySQLi's interface for prepared statements is procedural and less intuitive compared to PDO.
  • Performance: MySQLi can be faster than PDO in some scenarios because it is optimized specifically for MySQL databases.

3. How do you connect to a MySQL database using PDO in PHP?

Answer: To connect to a MySQL database using PDO in PHP, you can use the following code snippet:

try {
    $dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
    $username = 'root';
    $password = 'password';
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

4. How do you perform a SELECT query using PDO and MySQLi?

Answer:

PDO:

$stmt = $pdo->query('SELECT * FROM users');
while ($row = $stmt->fetch()) {
    echo $row['username'] . "<br>";
}

MySQLi Procedural:

$result = mysqli_query($conn, 'SELECT * FROM users');
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['username'] . "<br>";
}

MySQLi Object-Oriented:

$result = $conn->query('SELECT * FROM users');
while ($row = $result->fetch_assoc()) {
    echo $row['username'] . "<br>";
}

5. What are prepared statements and how do you use them with PDO and MySQLi?

Answer: Prepared statements are used to execute the same SQL query repeatedly with different parameters. They help prevent SQL injection by separating SQL logic from data.

PDO:

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

MySQLi Procedural:

$stmt = mysqli_prepare($conn, 'SELECT * FROM users WHERE id = ?');
mysqli_stmt_bind_param($stmt, 'i', $id);
$id = 1;
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
echo $row['username'];

MySQLi Object-Oriented:

$stmt = $conn->prepare('SELECT * FROM users WHERE id = ?');
$stmt->bind_param('i', $id);
$id = 1;
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo $row['username'];

6. How can you handle errors in PDO and MySQLi?

Answer:

PDO: PDO can throw exceptions or return error codes. Setting PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION allows catching exceptions.

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
    $stmt = $pdo->query('SELECT * FROM non_existent_table');
} catch (PDOException $e) {
    echo 'Error: ' . $e->getMessage();
}

MySQLi: MySQLi provides methods like error and errno to check for errors.

Procedural:

if (!$result = mysqli_query($conn, 'SELECT * FROM non_existent_table')) {
    echo 'Error: ' . mysqli_error($conn);
}

Object-Oriented:

if (!$result = $conn->query('SELECT * FROM non_existent_table')) {
    echo 'Error: ' . $conn->error;
}

7. What are the advantages of using PDO over MySQLi?

Answer:

  • Database Portability: PDO supports multiple databases, making it suitable for future changes or when working with multiple databases.
  • Unified API: PDO provides a consistent object-oriented API that is easier to use.
  • Prepared Statements: PDO's prepared statement interface is more intuitive and powerful.
  • Comprehensive Error Reporting: PDO throws exceptions by default, which is a better approach for error handling.

8. Can you use transactions with PDO and MySQLi?

Answer: Yes, both PDO and MySQLi support transactions.

PDO:

try {
    $pdo->beginTransaction();
    $pdo->exec('INSERT INTO users (username) VALUES ("Alice")');
    $pdo->exec('INSERT INTO users (username) VALUES ("Bob")');
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}

MySQLi:

try {
    mysqli_begin_transaction($conn);
    mysqli_query($conn, 'INSERT INTO users (username) VALUES ("Alice")');
    mysqli_query($conn, 'INSERT INTO users (username) VALUES ("Bob")');
    mysqli_commit($conn);
} catch (Exception $e) {
    mysqli_rollback($conn);
    throw $e;
}

9. How do you fetch results in different formats using PDO and MySQLi?

Answer:

PDO:

  • PDO::FETCH_ASSOC: Fetches a result row as an associative array.
  • PDO::FETCH_NUM: Fetches a result row as a numeric array.
  • PDO::FETCH_BOTH: Fetches a result row as both an associative and numeric array.

MySQLi:

  • mysqli_fetch_assoc(): Fetches a result row as an associative array.
  • mysqli_fetch_row(): Fetches a result row as a numeric array.
  • mysqli_fetch_array(): Fetches a result row as an array specified by a fetch type.

10. Which one should I choose, PDO or MySQLi?

Answer: The choice between PDO and MySQLi largely depends on your project requirements:

  • If you are working with multiple database types or prefer a more object-oriented approach, PDO is the better choice.
  • For performance and MySQL-specific features (like async queries available in MySQL 5.7+), MySQLi might be more suitable.

You May Like This Related .NET Topic

Login to post a comment.