thecodingmachine / Safe

Licence: mit
All PHP functions, rewritten to throw exceptions instead of returning false

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to Safe

Exception Track
Tracking ⚠️ exceptions for Rails application and store them in database.
Stars: ✭ 102 (-94.6%)
Mutual labels:  exceptions
Graphql Serverless
GraphQL (incl. a GraphiQL interface) middleware for the webfunc serverless web framework.
Stars: ✭ 124 (-93.44%)
Mutual labels:  functions
Gofn
Function process via docker provider (serverless minimalist)
Stars: ✭ 134 (-92.91%)
Mutual labels:  functions
Zip It And Ship It
Intelligently prepare Node.js Lambda functions for deployment
Stars: ✭ 104 (-94.5%)
Mutual labels:  functions
Tissue
Create Github issues from your code's Exceptions
Stars: ✭ 116 (-93.86%)
Mutual labels:  exceptions
Kcc
k crash course
Stars: ✭ 127 (-93.28%)
Mutual labels:  functions
Laravel Exception Notifier
Laravel Exception Notifier will send an email of the error along with the stack trace to the chosen recipients. This Package includes all necessary traits, views, configs, and Mailers for email notifications upon your applications exceptions. You can customize who send to, cc to, bcc to, enable/disable, and custom subject or default subject based on environment. Built for Laravel 5.2, 5.3, 5.4, 5.5+. Get the errors and fix them before the client even reports them, that's why this exists! For Laravel 5, 6, and 7
Stars: ✭ 94 (-95.03%)
Mutual labels:  exceptions
Openwhisk Devtools
Development tools for building and deploying Apache OpenWhisk
Stars: ✭ 141 (-92.54%)
Mutual labels:  functions
Serverlesslibrary
Source code for the Azure Serverless Community Library
Stars: ✭ 119 (-93.7%)
Mutual labels:  functions
Composer
Composer is a new programming model for composing cloud functions built on Apache OpenWhisk.
Stars: ✭ 131 (-93.07%)
Mutual labels:  functions
Backoff
Python library providing function decorators for configurable backoff and retry
Stars: ✭ 1,670 (-11.64%)
Mutual labels:  exceptions
Periskop
Exception Monitoring Service
Stars: ✭ 115 (-93.92%)
Mutual labels:  exceptions
Fdk Java
Java API and runtime for fn.
Stars: ✭ 127 (-93.28%)
Mutual labels:  functions
Didyoumean Python
Module to have suggestions in case of errors (NameError, AttributeError, etc).
Stars: ✭ 102 (-94.6%)
Mutual labels:  exceptions
Store
Official Function and Template Store for OpenFaaS
Stars: ✭ 136 (-92.8%)
Mutual labels:  functions
Ahk Rare
My collection of rare and maybe very useful functions
Stars: ✭ 101 (-94.66%)
Mutual labels:  functions
Echo
Python package containing all custom layers used in Neural Networks (Compatible with PyTorch, TensorFlow and MegEngine)
Stars: ✭ 126 (-93.33%)
Mutual labels:  functions
Faas Netes
Serverless on Kubernetes with OpenFaaS
Stars: ✭ 1,875 (-0.79%)
Mutual labels:  functions
Idaobjctypes
A collection of types & functions definitions useful for Objective-C binaries analysis.
Stars: ✭ 138 (-92.7%)
Mutual labels:  functions
Applicationinsights Dotnet Server
Microsoft Application Insights for .NET Web Applications
Stars: ✭ 130 (-93.12%)
Mutual labels:  exceptions

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

Safe PHP

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

to install rector/rector.

Run

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

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].