Part 6 of a bespoke in-company training. Complete set of slides under:
Part 1: https://www.slideshare.net/VasilyKartashov/effective-php-part-1
Part 2: https://www.slideshare.net/VasilyKartashov/effective-php-part-2
Part 3: https://www.slideshare.net/VasilyKartashov/effective-php-part-3
Part 4: https://www.slideshare.net/VasilyKartashov/effective-php-part-4
Part 5: https://www.slideshare.net/VasilyKartashov/effective-php-part-5
Part 6: https://www.slideshare.net/VasilyKartashov/effective-php-part-6
More about the author: http://notes.kartashov.com/about/
2. Use PSR-3 logger
This is a de-facto standard for PHP logging and serves a common denominator. As with all
common denominators it offers less than individual libraries but exclusive usage of
LoggerInterface in our code makes us:
● independent of specific libraries
● hopefully will be one day supported natively
3. Logging levels
Emergency System is unusable
Alert Actions must be taken immediately. Examples: website’s down,
database is unavailable.
Critical Critical condition. Example: Application component unavailable,
unexpected exception.
Error Runtime conditional that don’t require immediate action but require
logging and monitoring
Warning Exceptional occurrences that are not errors: poor API usage,
deprecated API usage, undesirable situations that are not necessarily
wrong
Info Interesting events, i.e. things I would like to see in the logs when browse
them
Debug Detailed debug information.
4. else, catch, pre-condition branches
As a general rule (not without exceptions) we should never have an implied else, empty catch,
or empty pre-condition branches
public function updateController(Controller $controller) {
if ($controller->virtual()) {
return;
}
try {
$controller->update();
} catch (Exception $e) {}
if ($controller->updated()) {
$controller->notify();
}
}
5. Pros & Cons
➔ Logging is tedious. Advantages of good
logs are seen not when you write them,
but when you read them 3 months later
➔ Empty “logging” branches clutter the
code
6. Use standard exceptions
Most of the time we don’t need to invent own exceptions. Bespoke exceptions are
required for 2 cases
● The bespoke exception should capture more information that a standard one, i.e.
not only message, code and source
● The bespoke exception is meant to be handled differently and should be caught in a
separate catch branch, thus type itself is important
If it’s not the case for you, use the standard one. Their meanings are stable and
“well-known”. http://php.net/manual/en/spl.exceptions.php
9. Include failure capture information
Exceptions are object and capture additional information. For example
UserEmailNotFoundException can have the $email varaible captured, as in
class UserEmailNotFoundException extends Exception {
private $email;
public function __Construct(string $email) { … }
public function email(): string {...}
}
if (($user = $userRepository->findUserByEmail($email)) === null) {
throw new UserEmailNotFoundException($email);
}
10. Pros & Cons
➔ A bit of more work
➔ Can pass additional information from a
very deeply nested context without
using global variables and similar tricks
11. Do not ignore exceptions
You have 3 options:
● Deal with an exception, if you know what to do with exceptional situation, for
example deadlock in the DB when you restart failed transaction
● Log the exception and re-throw if you’re not sure about whether the caller has a
strategy for exception handling, for example when a URL cannot be accessed
● Don’t try-catch if you’re sure it’s the caller’s responsibility to handle it, for example
when the illegal parameters are passed into a method
In any case never:
try {...} catch (...) { // ignore }