code quality and tooling
Handling Warnings, Notices, Deprecations, and Fatal Errors
PHP reports different kinds of problems with different severity levels. A junior developer should not ignore these messages or hide them with suppression. The useful habit is to identify what the message means, decide whether the code can continue, and fix the assumption that caused the problem.
This lesson focuses on four common categories: warnings, notices, deprecations, and fatal errors.
Warnings usually mean unsafe assumptions
A warning means PHP detected a problem while running the script. The script may continue, but the result may be wrong.
Accessing a missing array key is a common example in modern PHP.
<?php
declare(strict_types=1);
$product = ['name' => 'Notebook'];
if (! array_key_exists('price', $product)) {
echo 'Cannot price product';
exit;
}
echo $product['price'];
// Prints:
// Cannot price product
The fix is to check the key before reading it, or validate the whole product before it reaches this code.
Notices point to suspicious code
Notices are lower-severity signals, but they still matter. They often mean the code relies on something unclear, missing, or outdated.
Even when PHP continues, treat the message as a prompt to make the code more deliberate. A clean development environment helps you see new problems quickly.
Deprecations warn about future breakage
A deprecation means the code still works now, but it uses behaviour that may be removed or changed in a future PHP version.
Do not treat deprecations as harmless just because the page still loads. In professional maintenance work, deprecations are often the early warning before a PHP upgrade becomes expensive.
A good response is:
- identify which feature or library call is deprecated
- check the recommended replacement
- update the code in a small, testable change
- avoid adding new deprecated usage
Fatal errors stop the script
A fatal error means PHP cannot continue the current request or command. Examples include calling an undefined function, loading a missing required file, or hitting a type error that is not handled.
<?php
declare(strict_types=1);
function formatMoney(int $pennies): string
{
return 'GBP ' . number_format($pennies / 100, 2);
}
echo formatMoney(499);
// Prints:
// GBP 4.99
If this function were misspelled at the call site, PHP would not be able to call it. The fix would be to correct the name or load the file that defines the function.
Some serious errors can be caught
Modern PHP represents many serious runtime failures as Throwable, including Exception and Error. That does not mean every error should be caught everywhere.
Catch errors at a sensible boundary when you can produce a useful response.
<?php
declare(strict_types=1);
function divide(int $total, int $count): int
{
if ($count === 0) {
throw new InvalidArgumentException('Count must be greater than zero.');
}
return intdiv($total, $count);
}
try {
echo divide(100, 0);
} catch (InvalidArgumentException $exception) {
echo 'Cannot calculate average: ' . $exception->getMessage();
}
// Prints:
// Cannot calculate average: Count must be greater than zero.
This is better than letting a low-level calculation failure leak to the user.
Choose the right response
Different messages need different responses:
- missing optional data: use a safe default or branch
- missing required data: validate and reject it
- deprecated code: replace it deliberately
- missing function or class: fix loading, naming, or autoloading
- type mismatch: validate or convert at the boundary
- fatal production issue: log it, alert if needed, and show a safe user-facing response
The wrong response is to hide the message without understanding it.
A small checklist
When PHP reports a problem, ask:
- What exact category and message did PHP report?
- Which file and line triggered it?
- Did the code continue, or did the script stop?
- Is the value optional or required?
- Should the fix be validation, a default, a replacement API, or a loading/autoloading fix?
- How can the fix be checked?
Before moving on, make sure you can describe the difference between a warning, a deprecation, and a fatal error, and choose a sensible fix for each.
Practice
Task: Choose The Right Error Response
For each situation, choose the most sensible response.
Situations
- A product array is missing a required
pricekey. - The application logs a deprecation from a library method that still works.
- A script calls
formatMonney()but the real function is namedformatMoney(). - A form field is optional and may be missing from the submitted data.
Requirements
- Identify whether each situation is likely a warning, deprecation, fatal error, or normal optional-data case.
- Say whether the fix should be validation, a safe default, a replacement API, or a naming/loading fix.
- Keep each answer short.
Show solution
A missing required
pricekey is likely to produce a warning if the code reads it directly. The fix should be validation, because the value is required.A deprecated library method is a deprecation. The fix should be to find and use the replacement API in a small, testable change.
Calling
formatMonney()when the real function isformatMoney()is a fatal error. The fix is a naming fix, or a loading/autoloading fix if the function exists in another file that was not loaded.A missing optional form field is a normal optional-data case. The fix is a safe default or an explicit branch, not an error.