61. What is PDO in PHP?
Define PHP Data Objects as a consistent database-access interface available through database-specific drivers. Explain PDO objects, DSNs, connections, prepared statements, bound values, result fetching, exceptions, transactions, persistent connections, and driver differences. Clarify that PDO is not an ORM and does not make SQL portable automatically.
PDO stands for PHP Data Objects. It gives PHP a consistent interface for accessing different databases through drivers. It supports prepared statements, parameter binding, result fetching, transactions, and exceptions. PDO is not an ORM, and database-specific SQL can still differ.
See the Code while reading this explanation.
PDO gives a PHP program one common way to communicate with several kinds of databases. The program opens a connection, sends instructions, supplies values, receives matching records, and can group several changes so they succeed or fail together. This makes application code more consistent when developers work with different database products. However, each database still has its own rules and features, so changing the database may require changes to the instructions the program sends. PDO helps PHP communicate with databases; it does not turn database records into application objects automatically.
- Would you like me to focus on basic PDO usage or also explain prepared statements, transactions, and driver differences?
- Should I show a short PHP example using a specific database such as MySQL?
PDO means PHP Data Objects. It is a PHP extension that provides a consistent database-access API while relying on a database-specific PDO driver underneath.
A PDO object normally represents a connection to a database. PHP creates it with a DSN, which means Data Source Name. The DSN identifies the PDO driver and contains connection information required by that driver. For example, a MySQL DSN can contain the host, port, database name, and character set.
For values that come from users or other untrusted sources, I normally use prepared statements instead of concatenating those values into SQL. I call prepare() with placeholders and then provide the values separately using execute(), bindValue(), or bindParam(). PDO treats those placeholders as data values rather than SQL identifiers. Exact preparation and binding behavior can depend on the PDO driver and whether native or emulated prepared statements are being used. Prepared statements are still the normal safe way to pass untrusted data values when used correctly.
Prepared-statement parameters cannot be used for table names, column names, sort directions, SQL keywords, or other identifiers. If an identifier must be dynamic, the application should choose it from a trusted allowlist instead of inserting arbitrary user input.
A PDOStatement object represents a prepared or executed statement. Results can be read with methods such as fetch() for one row or fetchAll() for multiple rows. A fetch mode such as PDO::FETCH_ASSOC can return each row as an associative array.
For error handling, modern PDO code should normally use PDO::ERRMODE_EXCEPTION. Database errors then raise PDOException, which allows the application to handle failures explicitly. Production code should avoid exposing raw database exception details to end users because they may reveal sensitive implementation information.
PDO supports transactions with beginTransaction(), commit(), and rollBack(). A transaction groups related database changes into one unit of work. If all required operations succeed, the application commits. If an operation fails, it can roll back the active transaction when the database, driver, and storage engine support transactional behavior. Isolation levels, locking behavior, supported SQL, and many transaction details are controlled by the database system rather than by PDO itself.
PDO can request persistent connections by setting PDO::ATTR_PERSISTENT when the driver supports them. A persistent connection can remain available for reuse by later PDO objects in the same relevant PHP process instead of requiring a new physical database connection every time. Persistence behavior depends on the PHP SAPI and PDO driver. Persistent connections should be used carefully because connection state can survive longer than expected and database connection capacity can become an operational concern.
The important portability limit is that PDO standardizes much of the PHP-facing API, not the SQL language itself. MySQL, PostgreSQL, SQLite, and other databases can differ in SQL syntax, data types, built-in functions, generated-key behavior, transaction features, and driver-specific PDO options. Moving an application to another database may therefore require SQL, schema, configuration, and application changes.
PDO is also not an ORM. An ORM usually maps application objects or models to database data and adds higher-level features such as relationships and query abstractions. PDO stays much closer to SQL: the developer writes the SQL and decides how returned rows are used.
- Choose the PDO driver required by the target database.
- Build the correct DSN and create the PDO connection.
- Configure appropriate error handling, normally PDO::ERRMODE_EXCEPTION.
- Prepare SQL with placeholders for data values.
- Pass values separately through execute(), bindValue(), or bindParam().
- Fetch results using the required fetch mode.
- Use a transaction when related writes must succeed or fail as one unit.
- Roll back an active transaction when an operation fails.
- Release PDO and PDOStatement references when they are no longer needed.
- Use persistent connections only when their driver, SAPI, connection-state, and capacity implications are understood.
PDO does not determine the main time or memory cost of a database query. The database still does the expensive work, and performance depends on the SQL, indexes, amount of data, query plan, locks, network communication, and returned result size. Fetching many rows also uses more application memory, especially with fetchAll(), because all selected rows can be stored in PHP memory at once. Prepared statements can be useful for repeated execution, but they do not automatically make a poorly designed query fast. Persistent connections may reduce repeated connection setup work, but they can keep database connections available for longer and must be managed with database capacity in mind. Maintenance can be easier because PDO provides a consistent PHP API, although database-specific SQL and behavior still have to be maintained.
<?php
declare(strict_types=1);
$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=app;charset=utf8mb4';
$username = 'app_user';
$password = 'app_password';
try {
$pdo = new PDO(
$dsn,
$username,
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
$statement = $pdo->prepare(
'SELECT id, email FROM users WHERE email = :email'
);
$statement->execute([
'email' => 'user@example.com',
]);
$user = $statement->fetch();
if ($user === false) {
echo "User not found\n";
} else {
echo 'ID: ' . $user['id'] . PHP_EOL;
echo 'Email: ' . $user['email'] . PHP_EOL;
}
} catch (PDOException $exception) {
fwrite(STDERR, "Database operation failed.\n");
exit(1);
}Interviewers want to confirm that the candidate understands PHP's standard database-access interface and can use it safely. A strong answer should distinguish PDO from its database-specific drivers, explain prepared statements and parameter binding, understand connection and transaction handling, and recognize that PDO does not replace SQL or provide ORM-style object mapping.
Common mistakes include saying PDO is a database or an ORM, or claiming that using PDO automatically makes SQL portable across databases. Another mistake is concatenating untrusted values into SQL instead of using prepared-statement parameters. Candidates should not claim that placeholders can safely represent table names, column names, sort directions, or other SQL identifiers. Other mistakes include ignoring database exceptions, forgetting to roll back an active failed transaction, assuming every PDO driver behaves identically, calling fetchAll() on very large result sets without considering PHP memory use, and enabling persistent connections without considering connection state and database capacity.
Start with one clear sentence: PDO is PHP's consistent database-access interface. Then explain the connection, DSN, prepared statements, bound values, fetching, exceptions, and transactions. Finish with the two important limits: PDO is not an ORM, and it does not make database-specific SQL automatically portable.









