PHPackages                             star/specification - 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. star/specification

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

star/specification
==================

Specification system to allow applying specification to a data source.

0.3.0(9mo ago)01.0k1[2 issues](https://github.com/yvoyer/php-specification/issues)MITPHPPHP ^7.0|^8.0CI passing

Since Dec 30Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/yvoyer/php-specification)[ Packagist](https://packagist.org/packages/star/specification)[ RSS](/packages/star-specification/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (4)Used By (0)

PHP Specification
=================

[](#php-specification)

[![Build Status](https://github.com/yvoyer/php-specification/actions/workflows/tests.yml/badge.svg)](https://github.com/yvoyer/php-specification/actions/workflows/tests.yml/badge.svg)

Specification system for php. Provides adapter for some libraries.

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

[](#installation)

Using [Composer](https://getcomposer.org): `composer require star/php-specification`

Usage
-----

[](#usage)

### With basic php array

[](#with-basic-php-array)

#### fetchAll()

[](#fetchall)

Fetch all items matching the specification

```
$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
$items = $result->fetchAll(EqualsTo::fromBoolean('alias', 'active', true));
echo $items->count(); // 2
echo $items->getValue(0, 'name')->toInteger(); // Jane
echo $items->getValue(1, 'name')->toInteger(); // Jack
```

#### fetchOne()

[](#fetchone)

Fetch single item matching the specification

**Note**: If the specification would result with more than one row, a [NotUniqueResult exception](src/Result/NotUniqueResult.php) will be thrown.

```
$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
$row = $result->fetchOne(EqualsTo::booleanValue('alias', 'active', false));
echo $row->count(); // 1
echo $row->getValue('name')->toInteger(); // Joe
```

#### exists()

[](#exists)

Fetch whether an item matches the specification

```
$data = [
    [
        'id' => 1,
        'name' => 'Joe',
        'active' => false,
    ],
    [
        'id' => 2,
        'name' => 'Jane',
        'active' => true,
    ],
    [
        'id' => 3,
        'name' => 'Jack',
        'active' => true,
    ],
];
$result = ArrayResult::fromRowsOfMixed(...$data);
echo $result->exists(EqualsTo::stringValue('alias', 'name', 'Joe')); // true
echo $result->exists(EqualsTo::stringValue('alias', 'name', 'Not found')); // false
```

Supported specifications
------------------------

[](#supported-specifications)

### EqualsTo

[](#equalsto)

Whether the property's value is matching exactly the provided value (`===`).

Example:

```
EqualsTo::stringValue('alias', 'name', 'Joe');
```

**Note**: Both values will be converted to a string in order to assert the equality.

### Between

[](#between)

Whether the property's numeric or date value is included between the left and right values.

Example:

```
Between::integers('alias', 'age', 18, 40);
Between::dates('alias', 'published_at', new \DateTime('1900-01-01'), new \DateTime('2000-01-01 12:34:56'));
```

**Note**: The format `Y-m-d H:i:s` is the only supported format used for comparison.

### Contains

[](#contains)

Whether the provided value is found at any position of the item's property (start, end, middle).

Example:

```
Contains::string('alias', 'name', 'Joe');
```

### EndsWith

[](#endswith)

Whether the provided value is found at the end of the item's property.

Example:

```
EndsWith::string('alias', 'name', 'Joe');
```

### Greater

[](#greater)

Whether the property's numeric or date value is greater than the provided value.

Example:

```
Greater::thanInteger('alias', 'age', 18);
Greater::thanDate('alias', 'born_at', new \DateTime('2000-01-01'));
```

### GreaterEquals

[](#greaterequals)

Whether the property's numeric or date value is greater or equal than the provided value.

Example:

```
GreaterEquals::thanInteger('alias', 'age', 18);
GreaterEquals::thanDate('alias', 'born_at', new \DateTime('2000-01-01'));
```

### InArray

[](#inarray)

Whether the property's value is contained in the range of provided values.

Example:

```
InArray::ofIntegers('alias', 'age', 18, 20, 34); // would return items with age 18, 20 or 34.
```

### IsEmpty

[](#isempty)

Whether the property's value is an empty value.

Example:

```
new IsEmpty('alias', 'name');
```

**Note**: Zero, boolean false are considered empty.

### IsNot

[](#isnot)

Inverse the provided specification.

Example:

```
new IsNot(Lower::thanInteger('alias', 'age', 18)); // would return items with age >= 19.
```

### IsNull

[](#isnull)

Whether the property's value is a null value.

Example:

```
new IsNull('alias', 'age');
```

**Note**: Zero, boolean false and empty string are not considered null.

### Lower

[](#lower)

Whether the property's numeric or date value is less than the provided value.

Example:

```
Lower::thanInteger('alias', 'age', 18);
Lower::thanDate('alias', 'age', new \DateTime('2000-01-01'));
```

### LowerEquals

[](#lowerequals)

Whether the property's numeric or date value is less or equal than the provided value.

Example:

```
LowerEquals::thanInteger('alias', 'age', 18);
LowerEquals::thanDate('alias', 'age', new \DateTime('2000-01-01'));
```

### StartsWith

[](#startswith)

Whether the provided value is found at the beginning of the item's property.

Example:

```
StartsWith::string('alias', 'name', 'Joe');
```

### Composites (And / Or)

[](#composites-and--or)

Using [AndX](src/AndX.php) and [OrX](src/OrX.php) you are able to configure a more complex specification to your need.

Example:

```
// equivalent to "name = 'Joe' AND active = true"
new AndX(
    EqualsTo::stringValue('alias', 'name', 'Joe'),
    EqualsTo::booleanValue('alias', 'active', true),
);

// equivalent to "name = 'Joe' OR active = true"
new OrX(
    EqualsTo::stringValue('alias', 'name', 'Joe'),
    EqualsTo::booleanValue('alias', 'active', true),
);
```

Ordering by properties
----------------------

[](#ordering-by-properties)

We can also order our specifications with 1 or more properties.

Example:

```
new AndX(
    OrderBy::desc('alias', 'is_active'),
    OrderBy::asc('alias', 'age'),
    OrderBy::desc('alias', 'name'),
);
new OrX(
    OrderBy::desc('alias', 'is_active'),
    OrderBy::asc('alias', 'age'),
    OrderBy::desc('alias', 'name'),
);
```

Supported frameworks
--------------------

[](#supported-frameworks)

- [PHP in memory array](src/Platform/InMemoryPlatform.php) using [ResultSet](src/Result/ResultSet.php) implementations.
- [Doctrine DBAL](src/Platform/DoctrineDBALPlatform.php)
- Doctrine ORM (TODO)

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance58

Moderate activity, may be stable

Popularity19

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

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

Total

3

Last Release

270d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/36116f724f1bd3ed808e54e2b2de6c17209c5c2c1954685fba18958ec8d055ee?d=identicon)[yvoyer](/maintainers/yvoyer)

---

Top Contributors

[![yvoyer](https://avatars.githubusercontent.com/u/1745744?v=4)](https://github.com/yvoyer "yvoyer (11 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/star-specification/health.svg)

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

###  Alternatives

[morilog/jalali

This Package helps developers to easily work with Jalali (Shamsi or Iranian) dates in PHP applications, based on Jalali (Shamsi) DateTime class.

9201.2M45](/packages/morilog-jalali)[bruli/php-git-hooks

Git hooks for PHP projects.

675370.8k5](/packages/bruli-php-git-hooks)[nikolaposa/version

Value Object that represents a SemVer-compliant version number.

1406.4M16](/packages/nikolaposa-version)[prooph/common

Common classes used across prooph packages

852.2M27](/packages/prooph-common)[funeralzone/valueobjects

A PHP 7.1 value objects helper library.

66643.3k22](/packages/funeralzone-valueobjects)[tomasnorre/crawler

Crawler extension for TYPO3

58397.5k1](/packages/tomasnorre-crawler)

PHPackages © 2026

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