PHPackages                             mf1dd/object-builder - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. mf1dd/object-builder

ActiveLibrary[Testing &amp; Quality](/categories/testing)

mf1dd/object-builder
====================

Automatically creates fully populated PHP object instances with random, type-safe values. Designed for test fixtures and runtime object generation. Supports all PHP class types — regular classes, readonly classes, abstract classes, enums, traits, interfaces, and built-in stock classes like DateInterval or ArrayObject. Recursively resolves nested object graphs, detects property names for semantically meaningful values (timezone, email, firstname …), and offers constraint-based value ranges via a fluent API. No framework required; zero runtime dependencies beyond nikic/php-parser. PHP 8.2+.

1.0.1(today)01↑2900%[2 issues](https://github.com/MF1DD/ObjectBuilder/issues)MITPHPPHP ^8.2

Since Jul 29Pushed today1 watchersCompare

[ Source](https://github.com/MF1DD/ObjectBuilder)[ Packagist](https://packagist.org/packages/mf1dd/object-builder)[ RSS](/packages/mf1dd-object-builder/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (9)Versions (43)Used By (0)

ObjectBuilder
=============

[](#objectbuilder)

Automatic object creation with random values for PHP 8.2+.

Why?
----

[](#why)

Manually creating test objects is repetitive, error-prone, and time-consuming — especially for deeply nested object graphs with dozens of properties. Every constructor change forces you to update all test fixtures.

**ObjectBuilder** solves this: class name in, fully populated instance out. Recursive, type-safe, with semantically meaningful values.

Advantages
----------

[](#advantages)

- **No boilerplate** — `ObjectBuilder::init(Foo::class)->build()`instead of manual `new Foo(...)` with 10 parameters
- **Type-safe** — reflection-based, supports all native and custom types including enums, interfaces, traits, abstract, and readonly classes
- **Deep object graphs** — nested dependencies are resolved automatically and recursively (`Person → Address → Street`)
- **Semantic values** — detects property names (`email`, `timezone`, `firstname`) and generates matching random values
- **Constraints** — value ranges and formats via the `with()` API: `->with('age', ['min' => 18, 'max' => 65])`
- **Overridable** — set specific properties to fixed values while keeping the rest random
- **Extensible** — custom type builders and stock class handlers can be registered, builders are swappable
- **No framework** — pure PHP library, zero external runtime dependencies except `nikic/php-parser`

Compatibility
-------------

[](#compatibility)

PHP VersionStatus8.2Fully supported, CI-tested8.3Fully supported, CI-tested8.4Fully supported, CI-tested8.5CI-tested (once available)- **Runtime dependency**: `nikic/php-parser ^5.0`
- **No framework** (Symfony, Laravel, etc.) required
- **Package name**: `mf1dd/object-builder`

Basic Usage
-----------

[](#basic-usage)

Simple classes are automatically populated with random values.

```
class Address
{
    public function __construct(
        private readonly mixed $street,
        private readonly string|int $zip,
        private readonly string $city,
        private readonly ?string $country,
        private readonly bool $mainResidence,
    ) {}
}

$result = ObjectBuilder::init(Address::class)->build();
// returns instance of Address with random values
```

You can override specific values. Unset values are generated randomly. Nested objects are resolved automatically.

```
class Person
{
    public function __construct(
        private readonly Name $name,
        private readonly int $age,
        private readonly Address $address,
    ) {}
}

$result = ObjectBuilder::init(Person::class, [
    'age' => 25,
    'name' => [
        'firstName' => 'Max',
        'lastName' => 'Mustermann'
    ],
    'address' => [
        'city' => 'Berlin',
    ]
])->build();
// $result->getAge() === 25
// $result->getName()->getFirstName() === 'Max'
// $result->getAddress()->getCity() === 'Berlin'
// $result->getAddress()->getZip() === random int|string
```

Enumerations
------------

[](#enumerations)

```
enum MyEnumeration: string
{
    case OK = 'OK';
    case WARNING = 'WARNING';
    case ERROR = 'ERROR';
}
```

```
$result = ObjectBuilder::init(MyEnumeration::class)->build();
// returns one of MyEnumeration cases
```

You can specify which values the enum should use.

```
$result = ObjectBuilder::init(MyEnumeration::class, ['OK'])->build();
// returns MyEnumeration::OK

$result = ObjectBuilder::init(MyEnumeration::class, ['WARNING', 'ERROR'])->build();
// returns one of MyEnumeration::WARNING|MyEnumeration::ERROR
```

Traits
------

[](#traits)

For traits, an anonymous class is created that uses the trait. Parameters passed to the TraitBuilder are ignored.

```
$result = ObjectBuilder::init(MyTrait::class)->build();
// returns {class@anonymous/...}
```

Interfaces
----------

[](#interfaces)

The given interface is loaded and a class is dynamically generated from it. It returns the interface with the required methods and implements the interface.

The return value of methods is determined and a random value is assigned.

```
$result = ObjectBuilder::init(MyInterface::class)->build();
// returns Object of MyInterfaceClass
$value = $result->myMethod()
// returns random value matching its return type.
```

You can specify which values the methods should return. Pass an array with the method name as the key.

```
$options = [
    'getMyString' => 'testString'
];

$result = ObjectBuilder::init(MyInterface::class, $options)->build();
// returns Object of MyInterfaceClass
$value = $result->getMyString()
// returns 'testString'
```

If a method returns an object and you want to set values in it, that works too.

```
$options = [
    'getMyObject' => new SomeObject('Gustav', 27)
];

$result = ObjectBuilder::init(MyInterface::class, $options)->build();
// returns Object of MyInterfaceClass
$value = $result->getMyObject()
/**
 * returns class SomeObject {
 *      string $name => "Gustav",
 *      int $age => 27,
 * }
 */
```

It is also possible to pass individual parameters to the object.

```
$options = [
    'getMyObject' => ['name' => 'Bernhard']
];

$result = ObjectBuilder::init(MyInterface::class, $options)->build();
// returns Object of MyInterfaceClass
$value = $result->getMyObject()
/**
 * returns class SomeObject {
 *      string $name => "Bernhard",
 *      int $age => 27356453,
 * }
 */
```

Readonly Classes
----------------

[](#readonly-classes)

Readonly classes (PHP 8.2+) are supported. Properties are automatically populated in the constructor — including nested ones.

```
readonly class ReadonlyPerson
{
    public function __construct(
        public string $name,
        public int $age,
        public ?ReadonlyAddress $address = null,
    ) {}
}

$result = ObjectBuilder::init(ReadonlyPerson::class, [
    'name' => 'Alice',
    'address' => ['street' => 'Main St', 'city' => 'Springfield'],
])->build();
// $result->name === 'Alice'
// $result->address->street === 'Main St'
```

Abstract Classes
----------------

[](#abstract-classes)

Abstract classes are resolved via existing concrete subclasses. The builder automatically finds a suitable implementation.

```
abstract class AbstractVehicle
{
    public function __construct(public readonly string $brand) {}
    abstract public function getType(): string;
}

class Car extends AbstractVehicle
{
    public function getType(): string { return 'car'; }
}

$result = ObjectBuilder::init(AbstractVehicle::class)->build();
// returns instance of Car (or another concrete subclass)
```

Stock Classes (PHP Built-Ins)
-----------------------------

[](#stock-classes-php-built-ins)

Built-in PHP classes like DateInterval, DatePeriod, DateTime, DateTimeImmutable, ReflectionFunction, ArrayObject, and SplFileInfo are automatically supported.

```
$interval = ObjectBuilder::init(DateInterval::class)->build();
// returns DateInterval('P7D')

$date = ObjectBuilder::init(DateTimeImmutable::class)->build();
// returns random DateTimeImmutable instance

$ref = ObjectBuilder::init(ReflectionFunction::class)->build();
// returns new ReflectionFunction('strlen')
```

Custom handlers for additional stock classes can be registered:

```
use MF1DD\Application\Services\StockClassHandlerService;

StockClassHandlerService::register(new MyCustomHandler());
```

Value Constraints (`with()`)
----------------------------

[](#value-constraints-with)

The `with()` method allows setting constraints for value ranges.

```
use MF1DD\UserInterface\ObjectBuilder;

$result = ObjectBuilder::init(Person::class)
    ->with('age', ['min' => 18, 'max' => 65])
    ->with('email', ['format' => 'email'])
    ->build();
// $result->getAge() is between 18 and 65
// $result->getEmail() is a random email address
```

Available constraints:

- `min` / `max` — value range for int and float
- `min_length` / `max_length` — string length
- `format` — predefined formats: `email`, `url`, `uuid`

Semantic String Detection
-------------------------

[](#semantic-string-detection)

The StringBuilder recognizes specific property names and generates matching values:

```
class User
{
    public function __construct(
        public readonly string $timezone,    // random IANA timezone
        public readonly string $countrycode, // random ISO country code
        public readonly string $email,       // random email address
        public readonly string $firstname,   // random first name
        public readonly string $lastname,    // random last name
        public readonly string $city,        // random city name
        public readonly string $street,      // random street name
        public readonly string $zip,         // random postal code
        public readonly string $phone,       // random phone number
        public readonly string $uuid,        // random UUID v4
        public readonly string $url,         // random URL
    ) {}
}

$result = ObjectBuilder::init(User::class)->build();
// All properties contain semantically meaningful random values
```

Custom Type Builders
--------------------

[](#custom-type-builders)

Custom type builders can be registered for specific data types:

```
use MF1DD\Application\Services\DataTypeService;
use MF1DD\Domain\DataTypeInterface;
use MF1DD\Domain\Dto\Property;

class CustomBuilder implements DataTypeInterface
{
    public function build(): mixed
    {
        return 'custom value';
    }

    public function setProperty(Property $property): self
    {
        return $this;
    }

    public function buildAsString(): string
    {
        return "'custom value'";
    }
}

DataTypeService::register('custom_type', new CustomBuilder());
```

Custom Builder Override
-----------------------

[](#custom-builder-override)

The automatically selected builder can be overridden:

```
use MF1DD\Domain\ClassBuilderInterface;

$result = ObjectBuilder::init(MyClass::class)
    ->withBuilder($myCustomBuilder)
    ->build();
```

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity65

Established project with proven stability

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

Total

2

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/253864547?v=4)[MF1DD](/maintainers/MF1DD)[@MF1DD](https://github.com/MF1DD)

---

Tags

randomtestfactoryFixturedatareflectionmockgeneratorobjectbuilder

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm, Rector

Code StyleECS

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mf1dd-object-builder/health.svg)

```
[![Health](https://phpackages.com/badges/mf1dd-object-builder/health.svg)](https://phpackages.com/packages/mf1dd-object-builder)
```

###  Alternatives

[mockery/mockery

Mockery is a simple yet flexible PHP mock object framework

10.7k516.1M26.1k](/packages/mockery-mockery)[nelmio/alice

Expressive fixtures generator

2.5k44.6M154](/packages/nelmio-alice)[zenstruck/foundry

A model factory library for creating expressive, auto-completable, on-demand dev/test fixtures with Symfony and Doctrine.

78813.1M132](/packages/zenstruck-foundry)[nyholm/nsa

See everything and do whatever you want. No privacy rule will stop us. Used in tests, debugging and fixtures to access properties and methods.

2286.2M85](/packages/nyholm-nsa)[brain/monkey

Mocking utility for PHP functions and WordPress plugin API

33913.7M438](/packages/brain-monkey)[trappar/alice-generator

Automatically generates alice fixture based on a set of objects

52185.5k1](/packages/trappar-alice-generator)

PHPackages © 2026

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