PHPackages                             serafim/dbc - 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. [Framework](/categories/framework)
4. /
5. serafim/dbc

ActiveLibrary[Framework](/categories/framework)

serafim/dbc
===========

Design by Contract framework for PHP

0.3.2(4y ago)31.3k1MITPHPPHP ^8.1

Since Mar 25Pushed 4y ago1 watchersCompare

[ Source](https://github.com/SerafimArts/Contracts)[ Packagist](https://packagist.org/packages/serafim/dbc)[ RSS](/packages/serafim-dbc/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (5)Dependencies (6)Versions (7)Used By (1)

Contracts
=========

[](#contracts)

Contracts for PHP, is a contract programming framework and test tool for PHP, which uses attributes to provide run-time checking. (In particular, this is not a static analysis tool.)

 [![](https://github.com/SerafimArts/Contracts/workflows/build/badge.svg)](https://github.com/SerafimArts/Contracts/actions) [![](https://camo.githubusercontent.com/4a242a6f3132d52d135aa0f61657c550dda59bfd4bf3e986dd132ae433210d8e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d5e382e312d6666303134302e737667)](https://packagist.org/packages/serafim/dbc) [![Latest Stable Version](https://camo.githubusercontent.com/34efdee754577cabcdc28e339d5243e8e567a03a15c295abe0e6f733072bcd89/68747470733a2f2f706f7365722e707567782e6f72672f7365726166696d2f6462632f76657273696f6e)](https://packagist.org/packages/serafim/dbc) [![Latest Unstable Version](https://camo.githubusercontent.com/2a1864b81763e7c18f65c46ddb0513959877e1b6361999b2976865ce3151908b/68747470733a2f2f706f7365722e707567782e6f72672f7365726166696d2f6462632f762f756e737461626c65)](https://packagist.org/packages/serafim/dbc) [![Total Downloads](https://camo.githubusercontent.com/a6e96a3ed23ea5a94a32796621e2be7d366b96c99c54391d63b8f4c0ed3efd8b/68747470733a2f2f706f7365722e707567782e6f72672f7365726166696d2f6462632f646f776e6c6f616473)](https://packagist.org/packages/serafim/dbc) [![License MIT](https://camo.githubusercontent.com/79b89cb4a5f888d840841f7b19ece24071531e14ad6d79cce9121c78742be873/68747470733a2f2f706f7365722e707567782e6f72672f6666692d686561646572732f76756c6b616e2d686561646572732f6c6963656e7365)](https://raw.githubusercontent.com/SerafimArts/Contracts/master/LICENSE.md)

Contents
--------

[](#contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
    - [Invariants](#invariants)
    - [Method Contracts](#method-contracts)
- [Features](#features)

Requirements
------------

[](#requirements)

- PHP 8.1+

Installation
------------

[](#installation)

Library is available as composer repository and can be installed using the following command in a root of your project.

```
$ composer require serafim/dbc
```

Configuration
-------------

[](#configuration)

By default, the behavior of contracts depends on whether assertions (`assert.active` in php.ini configuration) are enabled on your system.

However, you can force them to enable or disable contracts:

```
use Serafim\Contracts\Runtime;

// Enable runtime contract assertions
Runtime::enable();

// Disable runtime contract assertions
Runtime::disable();

// Enable runtime contract assertions if PHP
// assertions are enabled or disable otherwise.
Runtime::auto();
```

By default, the framework does not listen to any namespaces. To add a namespace for your application, use the `Runtime::listen()` method.

```
use Serafim\Contracts\Runtime;

Runtime::listen('App\\Entity', 'App\\Http\\Controllers');
```

In addition, you can specify the directory where the cache files should be stored.

> Please note that these cache files are included by the PHP, therefore they are cached by opcache extension and do not degrade performance.

```
use Serafim\Contracts\Runtime;

Runtime::cache(__DIR__ . '/storage');
```

Usage
-----

[](#usage)

Contracts are written as PHP code within quoted strings, embedded in attributes. E.g., `#[Verify('$x < 100')]` states that `$x` must be less than `100`. Any PHP expression, except anonymous classes, may be used, provided the string is properly escaped.

An annotation binds a contract to a code element: either a method or a class. Library defines three main annotation types, which live in the `Serafim\Contracts\Attribute` namespace:

- `#[Verify]` for method preconditions;
- `#[Ensure]` for method postconditions;
- `#[Invariant]` for class invariants;

Contract annotations work only (yet) with classes.

### Invariants

[](#invariants)

A class may have associated invariants. Instead of specifying a contract between a caller and a callee, those invariants describe the state of a valid object of the qualified type. Calling methods on an object may cause it to change; invariants guarantee that after any such change, the object remains in a consistent state.

Of course, internal operations are allowed to muck around and temporarily invalidate invariants to do their job, but they agree to eventually put everything back into their proper places. Intuitively, any operation made against this is considered internal and does not need to obey the invariants. Only method invocations on other variables do.

Any defined invariant in a class has access to all of its fields, including any protected and private.

```
use Serafim\Contracts\Attribute\Invariant;

#[Invariant('$this->balance >= 0')]
class Account
{
    private int $balance = 0;

    public function deposit(int $amount): void
    {
        $this->balance += $amount + 1;
    }
}
```

When determining such an invariant, the account's balance will always be greater or equal than zero.

```
$account = new Account();

$account->deposit(42);      // OK
$account->deposit(-666);    // Serafim\Contracts\Exception\InvariantException: $this->balance >= 0
```

### Method contracts

[](#method-contracts)

A method may have preconditions and postconditions attached to it. Together, they specify the contract between caller and callee: if the precondition is satisfied on entry of the method, then the caller may assume the postcondition on exit. The precondition is what the callee demands of the caller, and in return the caller expects the postcondition to hold after the call.

As an example, consider the following specification of the square root function, which states that for any non-negative double x given, sqrt will return a non-negative result.

```
use Serafim\Contracts\Attribute\Verify;
use Serafim\Contracts\Attribute\Ensure;

class Math
{
    #[Verify('x >= 0')]
    #[Ensure('$result >= 0')]
    public static function sqrt(float $x): float
    {
        // ...code
    }
}
```

As shown in this example, a precondition may access parameter values; in fact, preconditions and postconditions are evaluated in the context of the method they are bound to. More precisely, each annotation behaves as if it were a method, with the same arguments and in the same scope as the qualified method. In terms of scoping, the previous code is equivalent to the following:

```
use Serafim\Contracts\Attribute\Verify;
use Serafim\Contracts\Attribute\Ensure;

class Math
{
    public static function sqrt(float $x): float
    {
        if ($x < 0) {
            throw new \Serafim\Contracts\Exception\PreconditionException('$x >= 0');
        }

        // ...code

        if ($result < 0) {
            throw new \Serafim\Contracts\Exception\PostconditionException('$result >= 0');
        }

        return $result;
    }
}
```

In addition, postconditions may contain a few extensions:

- As we have seen, they may refer to the returned value, using the `$result`keyword.
- Within a postcondition,`$old` is a keyword that contains the state of the object before its changes.

At run time, when contracts are enabled, preconditions and postconditions translate to checks on entry and exit, respectively, of the method. A failure results in a `PreconditionException` or `PostconditionException` being thrown, depending on the origin: failure to meet a precondition means that the method was called incorrectly, whereas an unsatisfied postcondition points to a bug in the implementation of the method itself.

#### Keywords

[](#keywords)

KeywordMay appear inDescription`$old``#[Ensure]`Value on method entry`$result``#[Ensure]`Value to be returned### Features

[](#features)

- Class Contracts
    - Abstract methods
    - Inheritance (import from parent classes, traits and interfaces)
- Trait Contracts
    - Abstract methods
- Interface Contracts

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity18

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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 ~2 days

Total

5

Last Release

1504d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/150420?v=4)[Ruslan Sharipov](/maintainers/Serafim)[@serafim](https://github.com/serafim)

---

Top Contributors

[![SerafimArts](https://avatars.githubusercontent.com/u/2461257?v=4)](https://github.com/SerafimArts "SerafimArts (29 commits)")

---

Tags

contractsdbcdesign-by-contractsensureinvariantphpverify

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/serafim-dbc/health.svg)

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

###  Alternatives

[silverstripe/framework

The SilverStripe framework

7213.5M2.5k](/packages/silverstripe-framework)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[spiral/framework

Spiral, High-Performance PHP/Go Framework

2.0k1.8M57](/packages/spiral-framework)[phalcon/devtools

This tools provide you useful scripts to generate code helping to develop faster and easy applications that use with Phalcon framework.

1.3k2.0M54](/packages/phalcon-devtools)[cakephp/bake

Bake plugin for CakePHP

11211.2M158](/packages/cakephp-bake)[contao/core-bundle

Contao Open Source CMS

1231.6M2.4k](/packages/contao-core-bundle)

PHPackages © 2026

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