PHPackages                             frontastic/rulerz - 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. [Database &amp; ORM](/categories/database)
4. /
5. frontastic/rulerz

ActiveLibrary[Database &amp; ORM](/categories/database)

frontastic/rulerz
=================

Powerful implementation of the Specification pattern

0.22.0(2y ago)045.8k↓40.7%2MITPHPPHP &gt;=7.1

Since Sep 2Pushed 2y agoCompare

[ Source](https://github.com/FrontasticGmbH/rulerz)[ Packagist](https://packagist.org/packages/frontastic/rulerz)[ Docs](https://github.com/K-Phoen/RulerZ)[ Patreon](https://www.patreon.com/kevin_gomez)[ RSS](/packages/frontastic-rulerz/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (4)Used By (2)

RulerZ [![Build Status](https://camo.githubusercontent.com/1a9ac8e5064e73aafe69d5eb5e5b4620646dd4352187d6d46b0245790b705484/68747470733a2f2f7472617669732d63692e6f72672f4b2d50686f656e2f72756c65727a2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/K-Phoen/rulerz) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/462dfba1cf746f53da67c4226ae11f596dad92d4db8492dbda1bc7262c899317/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4b2d50686f656e2f72756c65727a2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/K-Phoen/rulerz/?branch=master)
==========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

[](#rulerz--)

> The central idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched against.
>
> Specifications, [explained by Eric Evans and Martin Fowler](http://www.martinfowler.com/apsupp/spec.pdf)

RulerZ is a PHP implementation of the **Specification pattern** which puts the emphasis on three main aspects:

- an easy and **data-agnostic [DSL](http://en.wikipedia.org/wiki/Domain-specific_language)**to define business rules and specifications,
- the ability to check if a candidate **satisfies** a specification,
- the ability to **filter or query any datasource** to only retrieve candidates matching a specification.

Introduction
------------

[](#introduction)

Business rules can be written as text using a dedicated language, very close to SQL, in which case we refer to them as *rules* or they can be encapsulated in single classes and referred to as *specifications*.

Once a rule (or a specification) is written, it can be used to check if a single candidate satisfies it or directly to query a datasource.

The following datasources are supported natively:

- array of arrays,
- array of objects.

And support for each one of these is provided by an additional library:

- Doctrine DBAL QueryBuilders: [rulerz-php/doctrine-dbal](https://github.com/rulerz-php/doctrine-dbal/),
- Doctrine ORM QueryBuilders: [rulerz-php/doctrine-orm](https://github.com/rulerz-php/doctrine-orm/),
- [Pomm](http://www.pomm-project.org/) models: [rulerz-php/pomm](https://github.com/rulerz-php/pomm/),
- Elasticsearch (using the [official client](https://github.com/elasticsearch/elasticsearch-php): [rulerz-php/elasticsearch](https://github.com/rulerz-php/elasticsearch/),
- Solr (using the [solarium](https://github.com/solariumphp/solarium): [rulerz-php/solarium](https://github.com/rulerz-php/solarium/),
- Laravel's [Eloquent ORM](http://laravel.com/docs/5.0/eloquent): [rulerz-php/eloquent](https://github.com/rulerz-php/eloquent/).

**Killer feature:** when working with Doctrine, Pomm, or Elasticsearch, RulerZ is able to convert rules directly in queries and does not need to fetch data beforehand.

#### That's cool, but why do I need that?

[](#thats-cool-but-why-do-i-need-that)

First of all, you get to **express business rules** in a dedicated, **simple language**. Then, these business rules can be **encapsulated** in specification classes, reused and composed to form more complex rules. Specifications are now **reusable** and **testable**. And last but not least, these rules can be used both to check if a candidate satisfies it and to **filter any datasource**.

If you still need to be conviced, you can read the whole reasoning in [this article](http://blog.kevingomez.fr/2015/02/07/on-taming-repository-classes-in-doctrine-among-other-things/).

Quick usage
-----------

[](#quick-usage)

As a quick overview, we propose to see a little example that manipulates a simple rule and several datasources.

#### 1. Write a rule

[](#1-write-a-rule)

The rule hereafter describes a "*high ranked female player*" (basically, a female player having more than 9000 points).

```
$highRankFemalesRule = 'gender = "F" and points > 9000';
```

#### 2. Define a datasource

[](#2-define-a-datasource)

We have the following datasources:

```
// a Doctrine QueryBuilder
$playersQb = $entityManager
    ->createQueryBuilder()
    ->select('p')
    ->from('Entity\Player', 'p');

// or an array of arrays
$playersArr = [
    ['pseudo' => 'Joe',   'gender' => 'M', 'points' => 2500],
    ['pseudo' => 'Moe',   'gender' => 'M', 'points' => 1230],
    ['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001],
];

// or an array of objects
$playersObj = [
    new Player('Joe',   'M', 40, 2500),
    new Player('Moe',   'M', 55, 1230),
    new Player('Alice', 'F', 27, 9001),
];
```

#### 3. Use a rule to query a datasource

[](#3-use-a-rule-to-query-a-datasource)

For any of our datasource, retrieving the results is as simple as calling the `filter` method:

```
// converts the rule in DQL and makes a single query to the DB
$highRankFemales = $rulerz->filter($playersQb, $highRankFemalesRule);
// filters the array of arrays
$highRankFemales = $rulerz->filter($playersArr, $highRankFemalesRule);
// filters the array of objects
$highRankFemales = $rulerz->filter($playersObj, $highRankFemalesRule);
```

#### 3. (bis) Check if a candidate satisfies a rule

[](#3-bis-check-if-a-candidate-satisfies-a-rule)

Given a candidate, checking if it satisfies a rule boils down to calling the `satisfies` method:

```
$isHighRankFemale = $rulerz->satisfies($playersObj[0], $highRankFemalesRule);
```

Going further
-------------

[](#going-further)

Check out [the documentation](doc/index.md) to discover what RulerZ can do for you.

License
-------

[](#license)

This library is under the [MIT](LICENSE) license.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity28

Limited adoption so far

Community24

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 89.1% 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

Unknown

Total

1

Last Release

973d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f318e1926ddf8a68ba7654777cef8c5e164c5ac22c176f9685cc34715b7d4ec0?d=identicon)[tobyS](/maintainers/tobyS)

![](https://www.gravatar.com/avatar/0efbde993c12c5386754d74128e633e7195a90d423307940707e540570c87563?d=identicon)[frontastic](/maintainers/frontastic)

![](https://www.gravatar.com/avatar/80ff77c23e505855056ec82d07dafb5e1a92087e31b65d4e3038af62ae3b315e?d=identicon)[frontastic-developers](/maintainers/frontastic-developers)

---

Top Contributors

[![K-Phoen](https://avatars.githubusercontent.com/u/66958?v=4)](https://github.com/K-Phoen "K-Phoen (418 commits)")[![bobdercole](https://avatars.githubusercontent.com/u/3331705?v=4)](https://github.com/bobdercole "bobdercole (14 commits)")[![hkovesdi](https://avatars.githubusercontent.com/u/53486704?v=4)](https://github.com/hkovesdi "hkovesdi (6 commits)")[![iainmckay](https://avatars.githubusercontent.com/u/1223726?v=4)](https://github.com/iainmckay "iainmckay (6 commits)")[![esserj](https://avatars.githubusercontent.com/u/1032205?v=4)](https://github.com/esserj "esserj (3 commits)")[![mantiz](https://avatars.githubusercontent.com/u/838666?v=4)](https://github.com/mantiz "mantiz (3 commits)")[![jdeniau](https://avatars.githubusercontent.com/u/1398469?v=4)](https://github.com/jdeniau "jdeniau (2 commits)")[![jdecool](https://avatars.githubusercontent.com/u/433926?v=4)](https://github.com/jdecool "jdecool (1 commits)")[![jhuet](https://avatars.githubusercontent.com/u/372409?v=4)](https://github.com/jhuet "jhuet (1 commits)")[![loicbourg](https://avatars.githubusercontent.com/u/4905942?v=4)](https://github.com/loicbourg "loicbourg (1 commits)")[![mikaelrandy](https://avatars.githubusercontent.com/u/187703?v=4)](https://github.com/mikaelrandy "mikaelrandy (1 commits)")[![mnapoli](https://avatars.githubusercontent.com/u/720328?v=4)](https://github.com/mnapoli "mnapoli (1 commits)")[![nclsHart](https://avatars.githubusercontent.com/u/833625?v=4)](https://github.com/nclsHart "nclsHart (1 commits)")[![pioneer32](https://avatars.githubusercontent.com/u/4023517?v=4)](https://github.com/pioneer32 "pioneer32 (1 commits)")[![pitchart](https://avatars.githubusercontent.com/u/2943883?v=4)](https://github.com/pitchart "pitchart (1 commits)")[![royopa](https://avatars.githubusercontent.com/u/442991?v=4)](https://github.com/royopa "royopa (1 commits)")[![syrm](https://avatars.githubusercontent.com/u/155406?v=4)](https://github.com/syrm "syrm (1 commits)")[![yvoyer](https://avatars.githubusercontent.com/u/1745744?v=4)](https://github.com/yvoyer "yvoyer (1 commits)")[![claudusd](https://avatars.githubusercontent.com/u/3321326?v=4)](https://github.com/claudusd "claudusd (1 commits)")[![estelsmith](https://avatars.githubusercontent.com/u/363670?v=4)](https://github.com/estelsmith "estelsmith (1 commits)")

---

Tags

specificationdoctrine

###  Code Quality

TestsBehat

### Embed Badge

![Health badge](/badges/frontastic-rulerz/health.svg)

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

###  Alternatives

[kphoen/rulerz

Powerful implementation of the Specification pattern

8831.3M6](/packages/kphoen-rulerz)[happyr/doctrine-specification

Specification Pattern for your Doctrine repositories

452915.0k8](/packages/happyr-doctrine-specification)[sonata-project/doctrine-orm-admin-bundle

Integrate Doctrine ORM into the SonataAdminBundle

46117.7M155](/packages/sonata-project-doctrine-orm-admin-bundle)[portphp/portphp

Data import/export workflow

2702.9M22](/packages/portphp-portphp)[sylius/grid-bundle

Amazing grids with support of filters and custom fields integrated into Symfony.

1358.3M44](/packages/sylius-grid-bundle)[omines/datatables-bundle

Symfony DataTables Bundle with native Doctrine ORM, Elastica and MongoDB support

2851.4M6](/packages/omines-datatables-bundle)

PHPackages © 2026

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