The way I’ve been handling errors in my PHP code works, but I have to admit, it’s becoming really tedious. Let me explain. Suppose I need to call a function in the middle of my code, check a variable’s value, or ensure a database query returned a valid result. When something fails, I end up writing another if/else
block, pushing all the code inside that new block. It gets messy and cumbersome pretty quickly.
I’ve been reading about try/catch
and it seems like a cleaner solution. Instead of constantly creating if/else
blocks, I could wrap everything inside a try
block, and if something fails, I could throw an exception. That way, the code jumps straight to the catch
block, much like how an else
block would work after a failed if
statement. It seems like a more efficient approach, but I’m still unsure whether this is considered a standard practice for handling errors.
Here’s what I’m trying to figure out: What’s the best way to handle both fatal and non-fatal errors in a PHP application? My goal is to avoid blank screens (which are terrible for user experience) and instead show meaningful error messages, while still allowing the page header and footer to display.
PHP Code (with Errors):
codeif($_GET['something'] == 'somevalue')
{
$output .= 'somecode';
// make a DB query, fetch a row
$row = $stmt->Fetch(PDO::ASSOC);
if($row != null)
{
$output .= 'morecode';
if(somethingIsOK())
{
$output .= 'yet more page output';
}
else
{
$error = 'something is most definitely not OK.';
}
}
else
{
$error = 'the row does not exist.';
}
}
else
{
$error = 'something is not a valid value';
}
if($error == '') // no error
{
// display $output on page
}
else // an error
{
// display whatever error occurred on the page
}
Issues:
- Repetitive
if/else
blocks: Every time I check for a condition, like whether the database query returns a valid result or whether the value is okay, I have to create a newif/else
block. It’s tedious and clutters the code. - Manual error handling: Instead of automating error handling, I’m manually checking and displaying errors, which leads to extra work and repetitive code.
Corrected PHP Code:
codeif (isset($_GET['something']) && $_GET['something'] === 'somevalue') {
$output = ''; // Initialize $output to prevent undefined variable issues
$error = ''; // Initialize $error variable
$output .= 'somecode';
// Simulate a DB query, using try/catch for error handling
try {
// Assuming $stmt is a valid PDO statement object
$stmt = $pdo->prepare("SELECT * FROM your_table WHERE condition = :condition");
$stmt->execute(['condition' => 'some_condition']);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
$output .= 'morecode';
if (somethingIsOK()) {
$output .= 'yet more page output';
} else {
$error = 'Something is most definitely not OK.';
}
} else {
$error = 'The row does not exist.';
}
} catch (Exception $e) {
$error = 'Database query failed: ' . $e->getMessage();
}
} else {
$error = 'Something is not a valid value.';
}
// Output the results based on whether an error occurred
if (empty($error)) {
// Display $output on the page
echo $output;
} else {
// Display the error on the page
echo "<p>Error: $error</p>";
}
Key Improvements
- Validation of
$_GET['something']
:- We added
isset($_GET['something'])
to check if the value exists before comparing it. This prevents potential warnings if the parameter isn’t set in the URL.
- We added
- Initialization of Variables:
- Both
$output
and$error
are initialized at the start of the block to avoid potential “undefined variable” errors.
- Both
- Database Query Using PDO:
- I replaced the placeholder query with a PDO
prepare()
andexecute()
call. This uses prepared statements to prevent SQL injection. Thefetch()
method withPDO::FETCH_ASSOC
safely fetches data from the database.
- I replaced the placeholder query with a PDO
- Error Handling with
try/catch
:- The database query is wrapped in a
try/catch
block to handle any exceptions that might occur (e.g., failed queries). This ensures that any issues are caught, and the user is shown a helpful error message instead of a blank screen.
- The database query is wrapped in a
- Using
empty()
for Error Checking:- Instead of checking if
$error == ''
, the code now usesempty($error)
to check if any error occurred. This approach is more robust and avoids issues with null or falsy values.
- Instead of checking if
Conclusion
By restructuring the code, we’ve made it more secure, readable, and easier to maintain. Error handling is improved with try/catch
blocks, the database queries are protected against SQL injection with prepared statements, and the input validation ensures no warnings are raised for missing $_GET
parameters.