This article explores how to use exceptions in MySQLi, covering various techniques to handle errors efficiently, and providing code examples to illustrate these concepts.
What Are Exceptions?
Exceptions are objects that represent an error or an unusual condition in a program. When an exception is thrown, the normal flow of the program is interrupted, and the control is transferred to an exception handler. This allows for a clean separation of error-handling logic from regular code, improving readability and maintainability.Setting Up MySQLi with Exceptions
To use exceptions with MySQLi, you first need to enable the exception mode. This can be done using the mysqli_report function.Code Example: Enabling Exception Mode
getMessage());
}
?>
In this code:
- mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) configures MySQLi to throw exceptions on errors.
- The try block contains the code that might throw an exception.
- The catch block handles the exception, outputting an error message if the connection fails.
Handling Exceptions in MySQLi
Handling exceptions effectively is essential for creating robust applications. Below are various techniques for handling exceptions in MySQLi.1. Basic Exception Handling
In the simplest form, exception handling involves wrapping MySQLi operations in a try-catch block.Code Example: Basic Exception Handling
query($sql);
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "
";
}
} catch (mysqli_sql_exception $e) {
echo "Error: " . $e->getMessage();
} finally {
$conn->close();
}
?>
In this example:
- The try block contains the database operations.
- The catch block catches any mysqli_sql_exception and displays an error message.
- The finally block ensures the database connection is closed.
2. Handling Specific Exceptions
You might want to handle different types of exceptions differently. PHP allows you to catch specific exception types and handle them accordingly.Code Example: Handling Specific Exceptions
query($sql);
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "
";
}
} catch (mysqli_sql_exception $e) {
if ($e->getCode() == 1045) { // Example error code for access denied
echo "Authentication error: " . $e->getMessage();
} elseif ($e->getCode() == 2002) { // Example error code for connection failure
echo "Connection error: " . $e->getMessage();
} else {
echo "Database error: " . $e->getMessage();
}
} finally {
$conn->close();
}
?>
In this example:
- Different types of mysqli_sql_exception are handled based on the error code.
3. Using Custom Exception Handlers
For more advanced error handling, you can create custom exception handlers. This approach allows you to encapsulate error-handling logic in a dedicated class, improving code organization and reusability.Code Example: Custom Exception Handler
conn = new mysqli($servername, $username, $password, $dbname);
} catch (mysqli_sql_exception $e) {
throw new DatabaseException("Database connection failed: " . $e->getMessage(), $e->getCode());
}
}
public function query($sql) {
try {
$result = $this->conn->query($sql);
return $result;
} catch (mysqli_sql_exception $e) {
throw new DatabaseException("Query failed: " . $e->getMessage(), $e->getCode());
}
}
public function __destruct() {
$this->conn->close();
}
}
try {
$db = new Database($servername, $username, $password, $dbname);
$result = $db->query("SELECT id, firstname, lastname FROM MyGuests");
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "
";
}
} catch (DatabaseException $e) {
echo "Error: " . $e->getMessage();
}
?>
In this example:
- DatabaseException is a custom exception class.
- Database is a class that encapsulates the database connection and query logic.
- The try-catch block catches DatabaseException and handles it accordingly.
4. Logging Exceptions
Logging exceptions is a best practice for monitoring and debugging applications. PHP’s error_log function can be used to log exception details.Code Example: Logging Exceptions
conn = new mysqli($servername, $username, $password, $dbname);
} catch (mysqli_sql_exception $e) {
$this->logError($e);
throw new DatabaseException("Database connection failed: " . $e->getMessage(), $e->getCode());
}
}
public function query($sql) {
try {
$result = $this->conn->query($sql);
return $result;
} catch (mysqli_sql_exception $e) {
$this->logError($e);
throw new DatabaseException("Query failed: " . $e->getMessage(), $e->getCode());
}
}
private function logError($e) {
$log = "Error: [" . $e->getCode() . "] " . $e->getMessage() . " - " . $e->getFile() . ":" . $e->getLine() . PHP_EOL;
error_log($log, 3, 'errors.log'); // Log error to a file
}
public function __destruct() {
$this->conn->close();
}
}
try {
$db = new Database($servername, $username, $password, $dbname);
$result = $db->query("SELECT id, firstname, lastname FROM MyGuests");
while ($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "
";
}
} catch (DatabaseException $e) {
echo "Error: " . $e->getMessage();
}
?>
In this example:
- logError method logs the exception details to a file named errors.log.
Using Transactions with Exception Handling
Transactions ensure that a series of database operations are executed as a single unit. If any operation fails, the transaction can be rolled back, ensuring data integrity. Combining transactions with exception handling provides a robust way to manage database operations.Code Example: Transactions with Exception Handling
conn = new mysqli($servername, $username, $password, $dbname);
} catch (mysqli_sql_exception $e) {
$this->logError($e);
throw new DatabaseException("Database connection failed: " . $e->getMessage(), $e->getCode());
}
}
public function query($sql) {
try {
$result = $this->conn->query($sql);
return $result;
} catch (mysqli_sql_exception $e) {
$this->logError($e);
throw new DatabaseException("Query failed: " . $e->getMessage(), $e->getCode());
}
}
public function beginTransaction() {
$this->conn->begin_transaction();
}
public function commit() {
$this->conn->commit();
}
public function rollback() {
$this->conn->rollback();
}
private function logError($e) {
$log = "Error: [" . $e->getCode() . "] " . $e->getMessage() . " - " . $e->getFile() . ":" . $e->getLine() . PHP_EOL;
error_log($log, 3, 'errors.log'); // Log error to a file
}
public function __destruct() {
$this->conn->close();
}
}
try {
$db = new Database($servername, $username, $password, $dbname);
$db->beginTransaction();
$db->query("INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', 'john.doe@example.com')");
$db->query("INSERT INTO MyGuests (firstname, lastname, email) VALUES ('Jane', 'Doe', 'jane.doe@example.com')");
$db->commit();
echo "New records created successfully";
} catch (DatabaseException $e) {
$db->rollback();
echo "Transaction failed: " . $e->getMessage();
}
?>
In this example:
- beginTransaction, commit, and rollback methods are used to manage transactions.
- If an exception occurs, the transaction is rolled back, ensuring data integrity.