PHPackages                             dzentota/domain-primitives - 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. dzentota/domain-primitives

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

dzentota/domain-primitives
==========================

A collection of reusable domain primitives for PHP applications

09PHP

Since Jul 9Pushed 10mo agoCompare

[ Source](https://github.com/dzentota/DomainPrimitives)[ Packagist](https://packagist.org/packages/dzentota/domain-primitives)[ RSS](/packages/dzentota-domain-primitives/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Domain Primitives
=================

[](#domain-primitives)

A comprehensive collection of reusable domain primitives for PHP applications, built on the robust [dzentota/typedvalue](https://github.com/dzentota/typedvalue) library. This package provides secure, validated, and immutable value objects that follow the "Parse, Don't Validate" principle from the AppSec Manifesto.

Features
--------

[](#features)

- 🎯 **Type-safe value objects** with automatic validation
- 🔒 **Immutable by design** - values cannot be changed after creation
- ✅ **Comprehensive validation** with detailed error reporting
- 🔄 **TryParse pattern** - safe parsing without exceptions
- 🔍 **Domain-specific validation** - tailored rules for each primitive type
- 🌐 **Rich domain models** - extensive utility methods for each primitive
- 🧪 **Production ready** - battle-tested validation logic

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

[](#installation)

```
composer require dzentota/domain-primitives
```

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

[](#requirements)

- PHP 8.1 or higher
- dzentota/typedvalue ^1.0

Available Domain Primitives
---------------------------

[](#available-domain-primitives)

### Network

[](#network)

- **Port** - Network port validation (1-65535) with type detection
- **ServiceUrl** - HTTP/HTTPS URL validation with parsing utilities

### Common

[](#common)

- **Email** - Email address validation with normalization and obfuscation

### Configuration

[](#configuration)

- **FeatureFlag** - Boolean flag parsing with multiple format support

### Database

[](#database)

- **DatabaseDsn** - Database connection string validation and parsing

### Identity

[](#identity)

- **UuidId** - UUID validation with version detection and generation

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

```
use DomainPrimitives\Network\Port;
use DomainPrimitives\Common\Email;
use DomainPrimitives\Configuration\FeatureFlag;

// Create from valid input
$port = Port::fromNative(3000);
echo $port->toInt(); // 3000
echo $port->isWellKnown() ? 'Well-known' : 'Not well-known'; // Not well-known

// Safe parsing without exceptions
if (Email::tryParse('user@example.com', $email, $validationResult)) {
    echo "Valid email: " . $email->getDomain(); // example.com
} else {
    echo "Invalid: " . $validationResult->getFirstError()->getMessage();
}

// Feature flag parsing
$flag = FeatureFlag::fromNative('enabled');
echo $flag->isEnabled() ? 'Feature is on' : 'Feature is off'; // Feature is on
```

Domain Primitives Reference
---------------------------

[](#domain-primitives-reference)

### Network\\Port

[](#networkport)

Validates network ports (1-65535) with additional port type detection:

```
use DomainPrimitives\Network\Port;

$port = Port::fromNative(443);

echo $port->toInt();          // 443
echo $port->isWellKnown();    // false (443 > 1023)
echo $port->isRegistered();   // true (1024-49151)
echo $port->isDynamic();      // false (49152-65535)
echo $port->isSecure();       // true (HTTPS port)
```

### Network\\ServiceUrl

[](#networkserviceurl)

HTTP/HTTPS URL validation with rich parsing capabilities:

```
use DomainPrimitives\Network\ServiceUrl;

$url = ServiceUrl::fromNative('https://api.example.com:8080/v1/users');

echo $url->getScheme();       // https
echo $url->getHost();         // api.example.com
echo $url->getPort();         // 8080
echo $url->getPath();         // /v1/users
echo $url->isSecure();        // true
echo $url->getEffectivePort(); // 8080

// Immutable transformations
$newUrl = $url->withPath('/v2/users');
$queryUrl = $url->withQuery('limit=10&offset=0');
```

### Common\\Email

[](#commonemail)

Email validation with normalization and utility features:

```
use DomainPrimitives\Common\Email;

$email = Email::fromNative('John.Doe+newsletter@gmail.com');

echo $email->getLocalPart();  // John.Doe+newsletter
echo $email->getDomain();     // gmail.com
echo $email->isPersonal();    // true (gmail.com is personal)
echo $email->isBusiness();    // false

// Gmail normalization (removes dots, plus addressing)
$normalized = $email->normalize();
echo $normalized->toString();  // johndoe@gmail.com

// Privacy protection
echo $email->obfuscate();     // J*******************m@gmail.com
```

### Configuration\\FeatureFlag

[](#configurationfeatureflag)

Smart boolean parsing supporting multiple formats:

```
use DomainPrimitives\Configuration\FeatureFlag;

// Supports: true/false, 1/0, yes/no, on/off, enabled/disabled
$flag1 = FeatureFlag::fromNative('enabled');
$flag2 = FeatureFlag::fromNative('1');
$flag3 = FeatureFlag::fromNative(true);

echo $flag1->isEnabled();     // true
echo $flag1->toBool();        // true
echo $flag2->isDisabled();    // false
```

### Database\\DatabaseDsn

[](#databasedatabasedsn)

Database connection string validation and parsing:

```
use DomainPrimitives\Database\DatabaseDsn;

$dsn = DatabaseDsn::fromNative('mysql:host=localhost;dbname=myapp;port=3306');

echo $dsn->getDriver();       // mysql
echo $dsn->getHost();         // localhost
echo $dsn->getPort();         // 3306
echo $dsn->getDatabaseName(); // myapp
echo $dsn->getDefaultPort();  // 3306
echo $dsn->isFileDatabase();  // false

// Special case handling
$sqlite = DatabaseDsn::fromNative('sqlite::memory:');
echo $sqlite->isInMemory();   // true
```

### Identity\\UuidId

[](#identityuuidid)

UUID validation with version detection and utilities:

```
use DomainPrimitives\Identity\UuidId;

// Generate new UUID
$uuid = UuidId::generate();
echo $uuid->toNative();       // e.g., 550e8400-e29b-41d4-a716-446655440000

// Parse existing UUID
$existing = UuidId::fromNative('550e8400-e29b-41d4-a716-446655440000');

echo $existing->getVersion();  // 4 (random)
echo $existing->isNil();       // false

// Format transformations
echo $existing->toShort();     // 550e8400e29b41d4a716446655440000
$binary = $existing->toBinary(); // Binary representation

// UUID v1 timestamp extraction (if applicable)
$timestamp = $existing->getTimestamp(); // DateTimeImmutable or null
```

Error Handling
--------------

[](#error-handling)

All domain primitives provide comprehensive error handling:

```
use DomainPrimitives\Network\Port;

// Exception-based (for known-good input)
try {
    $port = Port::fromNative(99999); // Invalid port
} catch (ValidationException $e) {
    echo $e->getMessage();
    print_r($e->getValidationErrors());
}

// TryParse pattern (for user input)
if (Port::tryParse($userInput, $port, $validationResult)) {
    echo "Valid port: " . $port->toInt();
} else {
    foreach ($validationResult->getErrors() as $error) {
        echo "Error: " . $error->getMessage() . "\n";
    }
}
```

Best Practices
--------------

[](#best-practices)

### 1. Use TryParse for User Input

[](#1-use-tryparse-for-user-input)

Always use `tryParse()` when dealing with untrusted input:

```
// Good: Safe parsing
if (Email::tryParse($_POST['email'], $email, $validationResult)) {
    // Process valid email
} else {
    // Handle validation errors gracefully
}

// Avoid: Direct fromNative with user input
try {
    $email = Email::fromNative($_POST['email']); // May throw
} catch (ValidationException $e) {
    // Exception handling is less elegant
}
```

### 2. Leverage Immutability

[](#2-leverage-immutability)

Domain primitives are immutable - transformations create new instances:

```
$originalUrl = ServiceUrl::fromNative('https://api.example.com/v1');
$newUrl = $originalUrl->withPath('/v2'); // Creates new instance
// $originalUrl is unchanged
```

### 3. Use Rich Domain Methods

[](#3-use-rich-domain-methods)

Take advantage of the rich domain-specific methods:

```
$email = Email::fromNative('user@gmail.com');

// Rich domain logic
if ($email->isPersonal()) {
    $businessEmail = $email->normalize(); // Apply Gmail rules
    $safe = $email->obfuscate(); // For logging
}
```

### 4. Validate Early and Consistently

[](#4-validate-early-and-consistently)

Always validate data at the boundaries of your application:

```
// Validate configuration at startup
$dsn = DatabaseDsn::fromNative($config['database_url']);
$port = Port::fromNative($config['server_port']);

// Use domain-specific validation
if ($email->isPersonal()) {
    // Handle personal email logic
}
```

Architecture
------------

[](#architecture)

This library is built on the [dzentota/typedvalue](https://github.com/dzentota/typedvalue) foundation and follows these principles:

- **Parse, Don't Validate** - Values are parsed into valid objects immediately
- **Immutability** - All values are read-only after creation
- **Type Safety** - Rich type system prevents many classes of bugs
- **Security First** - Secure validation with detailed error reporting
- **Domain-Rich** - Each primitive includes relevant domain methods

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

[](#contributing)

Contributions are welcome! Please ensure:

1. All tests pass: `composer test`
2. Code follows PSR-12 standards
3. New primitives include comprehensive tests
4. Documentation is updated

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) file for details.

Related Libraries
-----------------

[](#related-libraries)

- **[dzentota/typedvalue](https://github.com/dzentota/typedvalue)** - Core typed value library
- **[dzentota/config-loader](https://github.com/dzentota/config-loader)** - Configuration management using these primitives

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance41

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

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.

### Community

Maintainers

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

---

Top Contributors

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

### Embed Badge

![Health badge](/badges/dzentota-domain-primitives/health.svg)

```
[![Health](https://phpackages.com/badges/dzentota-domain-primitives/health.svg)](https://phpackages.com/packages/dzentota-domain-primitives)
```

###  Alternatives

[aune-io/magento2-product-category-url-fix

Product category url fix for Magento 2

165.9k](/packages/aune-io-magento2-product-category-url-fix)

PHPackages © 2026

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