PHPackages                             thecodingmachine/safe - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. thecodingmachine/safe

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

thecodingmachine/safe
=====================

PHP core functions that throw exceptions instead of returning FALSE on error

v3.4.0(3mo ago)2.5k95.7M—7.4%167[31 issues](https://github.com/thecodingmachine/safe/issues)[5 PRs](https://github.com/thecodingmachine/safe/pulls)20MITPHPPHP ^8.1CI failing

Since Sep 11Pushed 2mo ago32 watchersCompare

[ Source](https://github.com/thecodingmachine/safe)[ Packagist](https://packagist.org/packages/thecodingmachine/safe)[ GitHub Sponsors](https://github.com/OskarStark)[ GitHub Sponsors](https://github.com/shish)[ RSS](/packages/thecodingmachine-safe/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (90)Used By (20)

[![Latest Version](https://camo.githubusercontent.com/45d93109c905db24a83a8901d895366af3950a1bbcb4f4feb2ec43059be8b5da/68747470733a2f2f706f7365722e707567782e6f72672f746865636f64696e676d616368696e652f736166652f762f737461626c652e737667)](https://packagist.org/packages/thecodingmachine/safe)[![Total Downloads](https://camo.githubusercontent.com/32d8641824a139c5efa117915deb1e94cc52c431063f168bafd5c852f89409c7/68747470733a2f2f706f7365722e707567782e6f72672f746865636f64696e676d616368696e652f736166652f646f776e6c6f6164732e737667)](https://packagist.org/packages/thecodingmachine/safe)[![License](https://camo.githubusercontent.com/0ca261ee6e30353328d025a1d2aa5308901ee642803f5078df125f5044df3f01/68747470733a2f2f706f7365722e707567782e6f72672f746865636f64696e676d616368696e652f736166652f6c6963656e73652e737667)](https://packagist.org/packages/thecodingmachine/safe)[![Tests](https://github.com/thecodingmachine/safe/workflows/Tests/badge.svg)](https://github.com/thecodingmachine/safe/actions)[![codecov](https://camo.githubusercontent.com/396a79a8b93cd3bb3032550723445604bda486e1ab90a38f4b81593ea10c6321/68747470733a2f2f636f6465636f762e696f2f67682f746865636f64696e676d616368696e652f736166652f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/thecodingmachine/safe)

Safe PHP
========

[](#safe-php)

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

The problem
-----------

[](#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 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) {
    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
------------

[](#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
-------------------

[](#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](https://github.com/phpstan/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
------------

[](#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
---------------------

[](#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](https://github.com/rectorphp/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
------------------

[](#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](performance/README.md)contains more information regarding the way we tested the performance impact of Safe.

Learn more
----------

[](#learn-more)

Read [the release article on TheCodingMachine's blog](https://thecodingmachine.io/introducing-safe-php) if you want to learn more about what triggered the development of Safe-PHP.

Contributing
------------

[](#contributing)

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

###  Health Score

79

—

ExcellentBetter than 100% of packages

Maintenance83

Actively maintained with recent releases

Popularity80

Widely adopted with strong download metrics

Community56

Growing community involvement

Maturity86

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~39 days

Recently: every ~70 days

Total

70

Last Release

103d ago

Major Versions

v0.1.16 → 1.0.0-beta12019-10-21

v1.3.3 → 2.0.0-alpha.12021-08-19

1.x-dev → v2.0.12022-01-05

v2.5.0 → 8.1.x-dev2023-04-13

PHP version history (4 changes)v0.1.0PHP &gt;=7.1

v1.0.0-beta2PHP &gt;=7.2

2.0.0-alpha.1PHP ^8.0

8.1.x-devPHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1104771?v=4)[mouf](/maintainers/mouf)[@Mouf](https://github.com/Mouf)

![](https://avatars.githubusercontent.com/u/1847918?v=4)[TheCodingMachine](/maintainers/thecodingmachine)[@thecodingmachine](https://github.com/thecodingmachine)

---

Top Contributors

[![Kharhamel](https://avatars.githubusercontent.com/u/10496706?v=4)](https://github.com/Kharhamel "Kharhamel (241 commits)")[![moufmouf](https://avatars.githubusercontent.com/u/1290952?v=4)](https://github.com/moufmouf "moufmouf (160 commits)")[![shish](https://avatars.githubusercontent.com/u/40659?v=4)](https://github.com/shish "shish (146 commits)")[![cedric-anne](https://avatars.githubusercontent.com/u/33253653?v=4)](https://github.com/cedric-anne "cedric-anne (25 commits)")[![localheinz](https://avatars.githubusercontent.com/u/605483?v=4)](https://github.com/localheinz "localheinz (20 commits)")[![silasjoisten](https://avatars.githubusercontent.com/u/10114981?v=4)](https://github.com/silasjoisten "silasjoisten (14 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (11 commits)")[![staabm](https://avatars.githubusercontent.com/u/120441?v=4)](https://github.com/staabm "staabm (10 commits)")[![asbiin](https://avatars.githubusercontent.com/u/25419741?v=4)](https://github.com/asbiin "asbiin (7 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (6 commits)")[![simPod](https://avatars.githubusercontent.com/u/327717?v=4)](https://github.com/simPod "simPod (5 commits)")[![jaydiablo](https://avatars.githubusercontent.com/u/136907?v=4)](https://github.com/jaydiablo "jaydiablo (5 commits)")[![jderusse](https://avatars.githubusercontent.com/u/578547?v=4)](https://github.com/jderusse "jderusse (5 commits)")[![dbrekelmans](https://avatars.githubusercontent.com/u/9531344?v=4)](https://github.com/dbrekelmans "dbrekelmans (5 commits)")[![jfoulquie-tnw](https://avatars.githubusercontent.com/u/159464174?v=4)](https://github.com/jfoulquie-tnw "jfoulquie-tnw (5 commits)")[![kunicmarko20](https://avatars.githubusercontent.com/u/13528674?v=4)](https://github.com/kunicmarko20 "kunicmarko20 (3 commits)")[![drobieux-julien](https://avatars.githubusercontent.com/u/26894758?v=4)](https://github.com/drobieux-julien "drobieux-julien (3 commits)")[![fezfez](https://avatars.githubusercontent.com/u/1162307?v=4)](https://github.com/fezfez "fezfez (3 commits)")[![ildyria](https://avatars.githubusercontent.com/u/627094?v=4)](https://github.com/ildyria "ildyria (3 commits)")[![martinssipenko](https://avatars.githubusercontent.com/u/598744?v=4)](https://github.com/martinssipenko "martinssipenko (3 commits)")

---

Tags

exceptionsfunctionsphp

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/thecodingmachine-safe/health.svg)

```
[![Health](https://phpackages.com/badges/thecodingmachine-safe/health.svg)](https://phpackages.com/packages/thecodingmachine-safe)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
