PHPackages                             kodzila/architecture-validator - 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. kodzila/architecture-validator

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

kodzila/architecture-validator
==============================

Library for validating PHP projects architecture.

0.1.0(4y ago)06PHPPHP ^7.4 | ^8.0

Since Sep 4Pushed 4y ago1 watchersCompare

[ Source](https://github.com/Kodzila/architecture-validator)[ Packagist](https://packagist.org/packages/kodzila/architecture-validator)[ RSS](/packages/kodzila-architecture-validator/feed)WikiDiscussions master Synced today

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

Architecture validator
======================

[](#architecture-validator)

Motivation
----------

[](#motivation)

Most projects are monoliths with some rules maintained to allow projects to scale if needed. Those rules must normally be enforced during code review and are exhausting to check each time.

This library aims to specify those rules explicitly by having a tool to check the rules automatically.

Inspiration was taken from Java [ArchUnit](https://github.com/TNG/ArchUnit) and not maintained anymore [PhpArch](https://github.com/j6s/phparch).

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

[](#installation)

Via composer:

```
composer require kodzila/architecture-validator --dev
```

Running
-------

[](#running)

Library itself does not provide any runner - it is only set of functionalities to validate rules. You need to write runner of your own choice.

### Runner: PHPUnit

[](#runner-phpunit)

Personally I recommend using this runner as it is quite easy to configure, and almost each project is shipped with that library.

- (If not already) Install PHPUnit:

```
composer require phpunit/phpunit --dev
```

- Create a test case in a directory of your choice. I prefer to configure it in `tests/Architecture/ArchitectureTest.php`:

```
use Kodzila\ArchValidator\Architecture;
use Kodzila\ArchValidator\Rule\CoreModuleRule;
use PHPUnit\Framework\TestCase;

final class ArchitectureTest extends TestCase
{
    public function test(): void
    {
        $architecture = Architecture::build()
            ->defineModule(
                'Core',
                'Isav\\Core\\',
                'src/Core'
            )
            ->defineModule(
                'Armap',
                'Isav\\Armap\\',
                'src/Armap'
            )
            ->defineModule(
                'Import',
                'Isav\\Import\\',
                'src/Import'
            )
        ;

        $architecture->checkRule(new CoreModuleRule('Core'));
        $this->assertTrue(true);
    }

}
```

- Create a new test suite in `phpunit.xml`:

```

            tests/Architecture

```

- Add script to `composer.json`:

```
"scripts": {
    "test:arch": [
        "bin/phpunit --testsuite Architecture"
    ]
}
```

- Now you can run validator with command:

```
composer test:arch
```

Concept
-------

[](#concept)

Unlike other modern OOP languages like Java and C#, PHP has no concept of packaging inside one project. The only thing are folders, but they cannot be restricted by scope modifiers.

As mentioned earlier, project can be a monolith application, but without any structure projects can quickly become a spaghetti code.

### Modular approach

[](#modular-approach)

The idea is that project source code can be bundled in *Modules*. Each module has a *Path* and corresponding PHP *Namespace*.

Consider such project:

```
.
+-- config
|   +-- services.yaml
|   +-- routing.yaml
+-- src
|   +-- Armap
|      +-- SyncService.php
|   +-- Core
|      +-- CoreEntity.php
|   +-- DoctrineMigrations
|      +-- Migration214312412.php
+-- tests
|   +-- E2E.php

```

You can see that project has been divided in modules: `Armap` and `Core`. Architecture validator can reflect such situation:

```
        $architecture = Architecture::build()
            ->defineModule(
                'Core',
                'Isav\\Core\\',
                'src/Core'
            )
            ->defineModule(
                'Armap',
                'Isav\\Armap\\',
                'src/Armap'
            )
        ;
```

Each module can contain set of PHP `classes`, `interfaces` and `traits` that will be analysed.

### Rules

[](#rules)

Architecture validator provides set of validators to check for common used approaches. They are called `Rules` and they can be found in `src/Rule/Extension`

#### CoreModuleRule

[](#coremodulerule)

Rule is assigning one module as `Core` module. Rest of registered modules are treated as `Submodule`.

Checks:

- `Core` module cannot depend on any `Submodule`.
- `Submodule` can depend on `Core` module, but cannot on any other `Submodule`.

This approach allows creating easy to maintain packages. Dependencies are only in one direction.

#### DomainDrivenDesignRule

[](#domaindrivendesignrule)

The rule is enforcing structures typical for this module architecture. Typical structure looks like that:

```
.
+-- Core
|   +-- Domain
|   +-- Application
|   +-- Infrastructure
|   +-- Presentation

```

You can read more about the structure [here](https://herbertograca.com/2017/09/07/domain-driven-design/).

Further, {Domain, Application, Infrastructure, Presentation} shall be called `Layers`

Checks:

- Domain layer cannot depend on any other layer.
- Application layer can depend only on Domain layer.

#### DomainForbiddenDependenciesRule

[](#domainforbiddendependenciesrule)

Domain is a heart of the system, and should not be polluted with unstable libraries. It should be well-tought process. The rule ensures that developers *thought* about implications of adding dependency into Domain layer.

[Quote:](https://www.infoq.com/articles/ddd-in-practice/)

```
Domain is the heart of the business application and should be well isolated from the other layers of the application.
Also, it should not be dependent on the application frameworks used in the other layers (JSP/JSF, Struts, EJB, Hibernate,
XMLBeans and so-on).

```

You need to add dependency whitelisted to ignore the error.

```
$architecture->checkRules([
    new DomainForbiddenDependenciesRule(['Core'], [
          'Doctrine\ORM\Mapping',
          'Doctrine\Common\Collections',
          'Ramsey\Uuid\UuidInterface',
    ])
]);
```

Development
-----------

[](#development)

- Clone the repository
- Install dependencies

```
composer install
```

### Release a new version

[](#release-a-new-version)

- Run `composer mr` (static code analysis) to make sure library code is up to standard.
- Add changes
- Commit changes
- Tag the changes
- Push to master

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

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

Unknown

Total

1

Last Release

1764d ago

### Community

Maintainers

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

---

Top Contributors

[![pawel-kozik](https://avatars.githubusercontent.com/u/174309081?v=4)](https://github.com/pawel-kozik "pawel-kozik (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/kodzila-architecture-validator/health.svg)

```
[![Health](https://phpackages.com/badges/kodzila-architecture-validator/health.svg)](https://phpackages.com/packages/kodzila-architecture-validator)
```

###  Alternatives

[composer/composer

Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.

29.5k196.2M3.1k](/packages/composer-composer)[friendsofphp/php-cs-fixer

A tool to automatically fix PHP code style

13.5k251.2M25.2k](/packages/friendsofphp-php-cs-fixer)[symfony/stimulus-bundle

Integration with your Symfony app &amp; Stimulus!

17417.5M295](/packages/symfony-stimulus-bundle)[illuminate/session

The Illuminate Session package.

9939.3M850](/packages/illuminate-session)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

103519.9k53](/packages/friendsoftypo3-content-blocks)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k43](/packages/civicrm-civicrm-core)

PHPackages © 2026

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