Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork162
All PHP functions, rewritten to throw exceptions instead of returning false
License
thecodingmachine/safe
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A set of core PHP functions rewritten to throw exceptions instead of returningfalse when an error is encountered.
Most PHP core functions were written before exception handling was added to the language. Therefore, most PHP functionsdo not throw exceptions. Instead, they returnfalse in case of error.
But most of us are too lazy to check explicitly for every single return of every core PHP function.
// This code is incorrect. Twice.// "file_get_contents" can return false if the file does not exist// "json_decode" can return false if the file content is not valid JSON$content =file_get_contents('foobar.json');$foobar =json_decode($content);
The correct version of this code would be:
$content =file_get_contents('foobar.json');if ($content ===false) {thrownewFileLoadingException('Could not load file foobar.json');}$foobar =json_decode($content);if (json_last_error() !==JSON_ERROR_NONE) {thrownewFileLoadingException('foobar.json does not contain valid JSON:'.json_last_error_msg());}
Obviously, while this snippet is correct, it is less easy to read.
Enterthecodingmachine/safe aka Safe-PHP.
Safe-PHP redeclares all core PHP functions. The new PHP functions act exactly as the old ones, except theythrow exceptions properly when an error is encountered. The "safe" functions have the same name as the core PHPfunctions, except they are in theSafe namespace.
usefunctionSafe\file_get_contents;usefunctionSafe\json_decode;// This code is both safe and simple!$content =file_get_contents('foobar.json');$foobar =json_decode($content);
All PHP functions that can returnfalse on error are part of Safe.In addition, Safe also provide 2 'Safe' classes:Safe\DateTime andSafe\DateTimeImmutable whose methods will throw exceptions instead of returning false.
Yeah... but I must explicitly think about importing the "safe" variant of the function, for each and every file of my application.I'm sure I will forget some "use function" statements!
Fear not! thecodingmachine/safe comes with a PHPStan rule.
Never heard ofPHPStan before?Check it out, it's an amazing code analyzer for PHP.
Simply install the Safe rule in your PHPStan setup (explained in the "Installation" section) and PHPStan will let you know each time you are using an "unsafe" function.
The code below will trigger this warning:
$content =file_get_contents('foobar.json');
Function file_get_contents is unsafe to use. It can return FALSE instead of throwing an exception. Please add 'use function Safe\file_get_contents;' at the beginning of the file to use the variant provided by the 'thecodingmachine/safe' library.
Use composer to install Safe-PHP:
composer require thecodingmachine/safe
Highly recommended: install PHPStan and PHPStan extension:
composer require --dev thecodingmachine/phpstan-safe-rule
Now, edit yourphpstan.neon file and add these rules:
includes: -vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
You have a large legacy codebase and want to use "Safe-PHP" functions throughout your project? PHPStan will help youfind these functions but changing the namespace of the functions one function at a time might be a tedious task.
Fortunately, Safe comes bundled with a "Rector" configuration file.Rector is a command-linetool that performs instant refactoring of your application.
Run
composer require --dev rector/rector
to installrector/rector.
Run
vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate.php
to runrector/rector.
Note: do not forget to replace "src/" with the path to your source directory.
Important: the refactoring only performs a "dumb" replacement of functions. It will not modify the way"false" return values are handled. So if your code was already performing error handling, you will have to dealwith it manually.
Especially, you should look for error handling that was already performed, like:
if (!mkdir($dirPath)) {// Do something on error}
This code will be refactored by Rector to:
if (!\Safe\mkdir($dirPath)) {// Do something on error}
You should then (manually) refactor it to:
try {\Safe\mkdir($dirPath));}catch (\Safe\FilesystemException$e) {// Do something on error}
Safe is loading 1000+ functions from ~85 files on each request. Yet, the performance impact of this loading is quite low.
In case you worry, using Safe will "cost" you ~700µs on each request. Theperformance sectioncontains more information regarding the way we tested the performance impact of Safe.
Readthe release article on TheCodingMachine's blog if you want tolearn more about what triggered the development of Safe-PHP.
The files that contain all the functions are auto-generated from the PHP doc.Read theCONTRIBUTING.md file to learn how to regenerate these files and to contribute to this library.
About
All PHP functions, rewritten to throw exceptions instead of returning false
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.