Database Connection
Database Connection Interview with follow-up questions
1. What is the purpose of a database connection in PHP?
A database connection in PHP provides the communication channel between the application and the database server. Its purposes are:
- Query execution: Run SELECT, INSERT, UPDATE, DELETE, and DDL statements.
- Data retrieval: Fetch result sets and iterate over rows.
- Transaction management: Group multiple operations into atomic units with COMMIT/ROLLBACK.
- Prepared statement support: Send parameterized queries to prevent SQL injection.
Establishing a connection with PDO (recommended):
$pdo = new PDO(
dsn: 'mysql:host=db.example.com;dbname=shop;charset=utf8mb4',
username: $username,
password: $password,
options: [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // use native prepared statements
]
);
Connection in modern PHP applications:
- Framework-managed: Laravel's
DBfacade and Eloquent, Symfony's Doctrine DBAL manage the connection lifecycle (opening, pooling, closing) for you. - Connection strings and credentials are stored in environment variables (
.env), never hardcoded. - Production deployments often use a connection pool via PgBouncer (PostgreSQL) or ProxySQL (MySQL) to reduce overhead of creating a new TCP connection per request.
Follow-up 1
How would you establish a database connection in PHP?
To establish a database connection in PHP, you can use the mysqli_connect() function or the PDO class. Here is an example of how to establish a database connection using mysqli_connect():
Follow-up 2
What are the steps involved in creating a database connection?
The steps involved in creating a database connection in PHP are as follows:
- Determine the server name or IP address of the database server.
- Determine the username and password to access the database.
- Determine the name of the database you want to connect to.
- Use the appropriate function or class to establish the database connection, such as
mysqli_connect()orPDO. - Check if the connection was successful and handle any errors that may occur.
Follow-up 3
What are the common errors you might encounter while establishing a database connection and how would you handle them?
Some common errors you might encounter while establishing a database connection in PHP are:
- Access denied: This error occurs when the username or password is incorrect. To handle this error, you can double-check the credentials and ensure they are correct.
- Connection refused: This error occurs when the database server is not running or is not accessible. To handle this error, you can check if the server is running and if the server name or IP address is correct.
- Unknown database: This error occurs when the specified database does not exist. To handle this error, you can check if the database name is correct or create the database if it does not exist.
It is important to handle these errors gracefully by displaying appropriate error messages to the user and logging the errors for debugging purposes.
2. What is the difference between MySQLi and PDO for database connection?
MySQLi and PDO are the two recommended extensions for database access in PHP. Choosing between them depends on your requirements:
MySQLi (MySQL Improved)
- MySQL-specific — only works with MySQL and MariaDB
- Supports both object-oriented (
$mysqli->query()) and procedural (mysqli_query()) styles - Supports MySQL-specific features: multiple statements,
LOAD DATA LOCAL INFILE, stored procedure output parameters - Slightly lower abstraction overhead for MySQL-only projects
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
$stmt = $mysqli->prepare('SELECT name FROM users WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
PDO (PHP Data Objects)
- Database-agnostic — supports MySQL, PostgreSQL, SQLite, SQL Server, Oracle via drivers
- Object-oriented API only
- Named placeholders (
:name) in addition to positional (?) - More consistent exception-based error handling
- Can switch databases by changing the DSN — useful for applications that support multiple database backends
$pdo = new PDO('mysql:host=localhost;dbname=app', $user, $pass);
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->execute([':id' => $id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
Recommendation: PDO is the standard choice for new projects. Use MySQLi only when you need MySQL-specific features not exposed by PDO, or when working in a MySQL-only codebase that already uses MySQLi.
Follow-up 1
What are the advantages and disadvantages of using MySQLi and PDO?
Advantages of using MySQLi:
- MySQLi is specifically designed for MySQL databases, so it provides better performance and compatibility with MySQL.
- MySQLi supports advanced features like multiple statements and transactions.
- MySQLi offers both procedural and object-oriented interfaces, giving developers flexibility in coding style.
Disadvantages of using MySQLi:
- MySQLi is limited to MySQL databases only, so it is not suitable for projects that may need to switch to a different database in the future.
Advantages of using PDO:
- PDO is a database abstraction layer that supports multiple databases, making it easier to switch between different databases without changing much code.
- PDO supports prepared statements, which can help prevent SQL injection attacks.
- PDO offers a consistent interface for all database operations, making it easier to learn and use.
Disadvantages of using PDO:
- PDO may have slightly lower performance compared to MySQLi, as it is a more general-purpose abstraction layer.
- PDO may have limited support for some database-specific features that are not available in all database drivers.
Follow-up 2
Can you provide an example of a database connection using PDO?
Sure! Here's an example of connecting to a MySQL database using PDO:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo 'Connected to the database!';
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
Follow-up 3
Can you provide an example of a database connection using MySQLi?
Certainly! Here's an example of connecting to a MySQL database using MySQLi:
connect_error) {
die('Connection failed: ' . $mysqli->connect_error);
}
echo 'Connected to the database!';
?>
3. How do you handle database connection errors in PHP?
Database connection errors should be caught and handled so the application fails gracefully and logs detailed information internally without exposing it to users.
PDO — recommended approach:
try {
$pdo = new PDO(
'mysql:host=localhost;dbname=app;charset=utf8mb4',
$_ENV['DB_USER'],
$_ENV['DB_PASS'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
// Log the real error (includes credentials context — keep internal)
error_log('Database connection failed: ' . $e->getMessage());
// Present a safe message to the user
http_response_code(503);
die('Service temporarily unavailable. Please try again later.');
}
MySQLi — check connect_errno:
$mysqli = new mysqli('localhost', $user, $pass, 'app');
if ($mysqli->connect_errno) {
error_log('MySQLi connection error: ' . $mysqli->connect_error);
http_response_code(503);
die('Database unavailable');
}
Framework approach (Laravel):
Laravel wraps PDO and throws Illuminate\Database\QueryException on errors. You can handle this in the application exception handler or using DB::reconnect() for retry logic.
Production best practices:
- Store credentials in environment variables (
.env), never hardcoded. - Never display raw
PDOExceptionmessages — they can contain the DSN, username, and server hostname. - Implement a retry mechanism for transient connection failures (especially in cloud environments).
- Use health-check endpoints that test connectivity without exposing error details.
Follow-up 1
What is the significance of the die() function in error handling?
The die() function in PHP is used to terminate the execution of a script and display a specified error message. It is commonly used in error handling to immediately stop the script when an error occurs. The die() function can be useful for displaying error messages to the user or for debugging purposes. However, it is important to note that using die() to handle errors is not considered best practice in larger applications, as it can make error handling and debugging more difficult.
Follow-up 2
What are some common database connection errors you might encounter?
Some common database connection errors you might encounter in PHP include:
- Access denied: This error occurs when the username or password used to connect to the database is incorrect.
- Host not found: This error occurs when the hostname or IP address of the database server is incorrect or unreachable.
- Connection timeout: This error occurs when the connection to the database server takes too long and times out.
- Too many connections: This error occurs when the maximum number of connections to the database server has been reached.
These are just a few examples, and there can be other errors depending on the specific database and configuration.
Follow-up 3
How would you log these errors for future debugging?
To log database connection errors for future debugging, you can use a logging library or write the error messages to a log file. Here is an example using the Monolog library:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$logger = new Logger('database');
$logger->pushHandler(new StreamHandler('path/to/log/file.log', Logger::ERROR));
try {
$pdo = new PDO('mysql:host=localhost;dbname=mydatabase', 'username', 'password');
} catch (PDOException $e) {
$logger->error('Database connection failed: ' . $e->getMessage());
die('Connection failed');
}
In this example, we are using the Monolog library to create a logger instance and configure it to write error messages to a log file. Inside the catch block, we log the error message using the error() method of the logger. This allows us to keep a record of the errors for future debugging.
4. What is persistent database connection and how is it different from normal database connection?
A persistent database connection reuses an existing connection from a connection pool rather than opening a new TCP connection to the database server on each PHP request.
Normal (non-persistent) connection:
- A new TCP connection is established at the start of each PHP script.
- The connection is closed (or returned to the OS) at the end of the script.
- Cost: TCP handshake + authentication overhead on every request.
Persistent connection:
- PHP checks whether a connection with matching credentials already exists in the process pool.
- If found, it reuses it; if not, it opens a new one.
- The connection is not closed at script end — it stays open in the PHP-FPM worker process.
Enabling with PDO:
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_PERSISTENT => true,
]);
Trade-offs:
| Normal | Persistent | |
|---|---|---|
| Overhead per request | Higher (new connection) | Lower (reuse existing) |
| Connection count | Bounded by active requests | Can accumulate |
| State isolation | Clean on each request | May carry leftover state (temp tables, locks, transactions) |
| Recommended for | Most web apps | High-throughput apps with short queries |
Important gotcha: Persistent connections can carry over uncommitted transactions, temporary tables, or session variables from previous requests if not properly cleaned up. In PHP-FPM environments, using a dedicated connection pooler (PgBouncer for PostgreSQL, ProxySQL for MySQL) is generally safer and more configurable than PHP's built-in persistent connections.
Follow-up 1
What are the advantages of using persistent connections?
There are several advantages of using persistent connections:
Improved performance: Reusing an existing connection eliminates the overhead of establishing a new connection, resulting in faster database access.
Reduced resource usage: Persistent connections reduce the number of connections created and closed, which can help conserve system resources.
Connection pooling: Persistent connections can be pooled and shared among multiple scripts, further optimizing resource usage.
Better scalability: With persistent connections, the database server can handle a larger number of concurrent requests without being overwhelmed by connection overhead.
Follow-up 2
What are the disadvantages of using persistent connections?
While persistent connections offer benefits, they also have some disadvantages:
Increased memory usage: Persistent connections consume memory on the server, as each connection remains open even when idle.
Connection limits: Some database servers impose limits on the number of concurrent persistent connections, which can restrict scalability.
Connection state issues: Persistent connections may retain state information from previous script executions, leading to unexpected behavior if not properly managed.
Compatibility issues: Not all database drivers or server configurations support persistent connections, limiting their usability in certain environments.
Follow-up 3
How would you establish a persistent database connection in PHP?
In PHP, you can establish a persistent database connection using the mysqli or PDO extension. Here's an example of establishing a persistent connection using mysqli:
connect_error) {
die('Connection failed: ' . $mysqli->connect_error);
}
// Use the connection for database operations
$mysqli->close(); // Close the connection
?>
Note the MYSQLI_CLIENT_PERSISTENT flag passed as the last argument to the mysqli constructor, which enables persistent connection.
5. How do you secure a database connection in PHP?
Securing a database connection in PHP involves several layers:
1. Use prepared statements — the single most important defense Prepared statements prevent SQL injection by separating query structure from data:
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
2. Store credentials in environment variables Never hardcode database credentials:
// .env (never commit to version control)
DB_HOST=localhost
DB_USER=appuser
DB_PASS=secretpassword
// In code
$pdo = new PDO(
'mysql:host=' . $_ENV['DB_HOST'] . ';dbname=app',
$_ENV['DB_USER'],
$_ENV['DB_PASS'],
);
3. Use least-privilege database accounts The application database user should have only the permissions it needs:
- SELECT, INSERT, UPDATE, DELETE on application tables
- No DROP, TRUNCATE, or GRANT permissions
- No access to
information_schemaormysqlsystem databases if avoidable
4. Enable SSL/TLS for connections to remote databases
$pdo = new PDO($dsn, $user, $pass, [
PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca-cert.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',
PDO::MYSQL_ATTR_SSL_KEY => '/path/to/client-key.pem',
]);
5. Enable exception mode and never expose errors
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
// + display_errors = Off in php.ini
6. Keep software updated — apply database server security patches promptly.
7. Firewall the database — restrict database port (3306 for MySQL) access to only the application servers.
Follow-up 1
What is SQL Injection and how can it be prevented?
SQL Injection is a type of attack where an attacker inserts malicious SQL statements into a query, which can manipulate the database or expose sensitive information. To prevent SQL Injection, you can follow these measures:
Use prepared statements or parameterized queries: Prepared statements or parameterized queries ensure that user input is treated as data and not executable code. This prevents attackers from injecting malicious SQL statements.
Use input validation and sanitization: Validate and sanitize user input to ensure it meets the expected format and does not contain any malicious code. Use functions like
filter_var()ormysqli_real_escape_string()to sanitize user input.Avoid dynamic SQL queries: Avoid constructing SQL queries by concatenating user input. Instead, use prepared statements or query builders that automatically handle escaping and sanitization.
Limit database user privileges: Grant only the necessary privileges to the database user. Avoid giving unnecessary permissions that can be exploited.
Regularly update software: Keep your PHP version, database server, and any related libraries or frameworks up to date to ensure you have the latest security patches.
Follow-up 2
What is the role of prepared statements in securing a database connection?
Prepared statements play a crucial role in securing a database connection by preventing SQL Injection attacks. Prepared statements are precompiled SQL statements that can be parameterized. They separate the SQL code from the data, treating user input as data rather than executable code. This prevents attackers from injecting malicious SQL statements.
When using prepared statements, the SQL statement is prepared once and then executed multiple times with different parameters. The parameters are bound to the prepared statement separately, ensuring that they are properly escaped and sanitized.
By using prepared statements, you can ensure that user input is treated as data and not as part of the SQL code. This significantly reduces the risk of SQL Injection attacks and helps to secure the database connection.
Follow-up 3
What other measures can be taken to secure a database connection?
In addition to using secure connection methods and prepared statements, there are other measures you can take to secure a database connection:
Encrypt sensitive data: Encrypt sensitive data before storing it in the database. This adds an extra layer of protection in case the database is compromised.
Implement two-factor authentication: Require users to provide an additional form of authentication, such as a one-time password or a biometric scan, to access the database.
Regularly backup the database: Regularly backup the database and store the backups in a secure location. This ensures that you can restore the database in case of data loss or a security breach.
Implement intrusion detection and prevention systems: Use intrusion detection and prevention systems to monitor and block any suspicious activity or unauthorized access attempts.
Follow the principle of least privilege: Grant only the necessary privileges to the database user. Avoid giving unnecessary permissions that can be exploited.
Regularly audit database activity: Monitor and review database activity logs to detect any unauthorized access or suspicious behavior.
Implement secure coding practices: Follow secure coding practices to minimize the risk of vulnerabilities that can be exploited to compromise the database connection.
Live mock interview
Mock interview: Database Connection
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.