Coder Social home page Coder Social logo

safe's Introduction

Latest Stable Version Total Downloads Latest Unstable Version License Build Status Continuous Integration Coverage Status

Safe PHP

Work in progress

A set of core PHP functions rewritten to throw exceptions instead of returning false when an error is encountered.

The problem

Most PHP core functions were written before exception handling was added to the language. Therefore, most PHP functions do not throw exceptions. Instead, they return false 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 exists
// "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) {
    throw new FileLoadingException('Could not load file foobar.json');
}
$foobar = json_decode($content);
if (json_last_error() !== JSON_ERROR_NONE) {
    throw new FileLoadingException('foobar.json does not contain valid JSON: '.json_last_error_msg());
}

Obviously, while this snippet is correct, it is less easy to read.

The solution

Enter thecodingmachine/safe aka Safe-PHP.

Safe-PHP redeclares all core PHP functions. The new PHP functions act exactly as the old ones, except they throw exceptions properly when an error is encountered. The "safe" functions have the same name as the core PHP functions, except they are in the Safe namespace.

use function Safe\file_get_contents;
use function Safe\json_decode;

// This code is both safe and simple!
$content = file_get_contents('foobar.json');
$foobar = json_decode($content);

All PHP functions that can return false on error are part of Safe. In addition, Safe also provide 2 'Safe' classes: Safe\DateTime and Safe\DateTimeImmutable whose methods will throw exceptions instead of returning false.

PHPStan integration

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 of PHPStan 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.

Installation

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 your phpstan.neon file and add these rules:

includes:
    - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon

Automated refactoring

You have a large legacy codebase and want to use "Safe-PHP" functions throughout your project? PHPStan will help you find 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-line tool that performs instant refactoring of your application.

Run

$ composer require --dev rector/rector:^0.7

to install rector/rector.

Run

vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate-0.7.yml

to run rector/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 deal with 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
}

Performance impact

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. The performance section contains more information regarding the way we tested the performance impact of Safe.

Learn more

Read the release article on TheCodingMachine's blog if you want to learn more about what triggered the development of Safe-PHP.

Contributing

The files that contain all the functions are auto-generated from the PHP doc. Read the CONTRIBUTING.md file to learn how to regenerate these files and to contribute to this library.

safe's People

Contributors

basilsnowman avatar bdsl avatar damianopetrungaro avatar danielruf avatar dmecke avatar drobieux-julien avatar jderusse avatar kasperg avatar kharhamel avatar kunicmarko20 avatar localheinz avatar mnapoli avatar moufmouf avatar nauxliu avatar noplanman avatar oskarstark avatar radimvaculik avatar reedy avatar simoheinonen avatar simpod avatar szepeviktor avatar thewilkybarkid avatar tigitz avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.