PHPackages                             tobento/app-seeding - 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. tobento/app-seeding

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

tobento/app-seeding
===================

App seeding support.

2.0(9mo ago)0100↓86.7%1MITPHPPHP &gt;=8.4

Since Dec 13Pushed 9mo ago1 watchersCompare

[ Source](https://github.com/tobento-ch/app-seeding)[ Packagist](https://packagist.org/packages/tobento/app-seeding)[ Docs](https://www.tobento.ch)[ RSS](/packages/tobento-app-seeding/feed)WikiDiscussions 2.x Synced yesterday

READMEChangelog (4)Dependencies (10)Versions (6)Used By (1)

App Seeding
===========

[](#app-seeding)

Seeding support for the app using the [Seeder Service](https://github.com/tobento-ch/service-seeder).

Table of Contents
-----------------

[](#table-of-contents)

- [Getting Started](#getting-started)
    - [Requirements](#requirements)
- [Documentation](#documentation)
    - [App](#app)
    - [Seeding Boot](#seeding-boot)
        - [Adding Seed Resources](#adding-seed-resources)
    - [Factories](#factories)
        - [Creating Factories](#creating-factories)
        - [Using Factories](#using-factories)
    - [Seeders](#seeders)
        - [Creating Seeders](#creating-seeders)
        - [Adding Seeders](#adding-seeders)
        - [Running Seeders](#running-seeders)
    - [User Seeding](#user-seeding)
    - [Repository](#repository)
        - [Creating Repository Factories](#creating-repository-factories)
- [Credits](#credits)

---

Getting Started
===============

[](#getting-started)

Add the latest version of the app seeding project running this command.

```
composer require tobento/app-seeding

```

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

[](#requirements)

- PHP 8.4 or greater

Documentation
=============

[](#documentation)

App
---

[](#app)

Check out the [**App Skeleton**](https://github.com/tobento-ch/app-skeleton) if you are using the skeleton.

You may also check out the [**App**](https://github.com/tobento-ch/app) to learn more about the app in general.

Seeding Boot
------------

[](#seeding-boot)

The seeding boot does the following:

- [*SeedInterface*](https://github.com/tobento-ch/service-seeder#create-seed) implementation
- SeedersInterface implementation
- adds console commands for seeding

The following seeders will be available:

- [*Resource Seeder*](https://github.com/tobento-ch/service-seeder#resource-seeder)
- [*DateTime Seeder*](https://github.com/tobento-ch/service-seeder#datetime-seeder)
- [*User Seeder*](https://github.com/tobento-ch/service-seeder#user-seeder)

Keep in mind that no [*Resources*](https://github.com/tobento-ch/service-seeder#resources) are set as they may be specific to your app needs. Therefore, the seeders mostly using the [*Lorem Seeder*](https://github.com/tobento-ch/service-seeder#lorem-seeder) as fallback.

```
use Tobento\App\AppFactory;
use Tobento\Service\Seeder\SeedInterface;
use Tobento\App\Seeding\SeedersInterface;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Seeding\Boot\Seeding::class);
$app->booting();

// Available Interfaces:
$seed = $app->get(SeedInterface::class);
$seeders = $app->get(SeedersInterface::class);

// Run the app
$app->run();
```

### Adding Seed Resources

[](#adding-seed-resources)

You may add seeder resources by the following ways:

**Globally by using the app `on` method**

```
use Tobento\App\AppFactory;
use Tobento\Service\Seeder\SeedInterface;
use Tobento\Service\Seeder\Resource;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots
$app->boot(\Tobento\App\Seeding\Boot\Seeding::class);
$app->booting();

// Add resources:
$app->on(SeedInterface::class, function(SeedInterface $seed) {

    $seed->resources()->add(new Resource('countries', 'en', [
        'Usa', 'Switzerland', 'Germany',
    ]));
});

$seed = $app->get(SeedInterface::class);

var_dump($seed->country());
// string(7) "Germany"

// Run the app
$app->run();
```

**Specific on any service using the seed**

```
use Tobento\Service\Seeder\SeedInterface;
use Tobento\Service\Seeder\Resource;

class ServiceUsingSeed
{
    public function __construct(
        protected SeedInterface $seed,
    ) {
        $seed->resources()->add(new Resource('countries', 'en', [
            'Usa', 'Switzerland', 'Germany',
        ]));
    }
}
```

Factories
---------

[](#factories)

### Creating Factories

[](#creating-factories)

You may create seed factories for testing or other purposes.

To create a factory, create a class that extends the `AbstractFactory::class` and configure your entity by using the `definition` method:

```
use Tobento\App\Seeding\AbstractFactory;

class UserFactory extends AbstractFactory
{
    public function definition(): array
    {
        return [
            'firstname' => $this->seed->firstname(),
            'role' => 'admin',
        ];
    }
}
```

**Creating entities**

You may use the `createEntity` method to create specific entites using the definition. By default, a `stdClass` class will be created.

```
use Tobento\App\Seeding\AbstractFactory;

class UserFactory extends AbstractFactory
{
    protected function createEntity(array $definition): object
    {
        return new User(
            firstname: $definition['firstname'],
        );
    }
}
```

**Storing entities**

By default, entities will not be stored. You may use the `storeEntity` method to store the entity based on the definition. In Addition, you may use `getService` method to get any service from the app container.

```
use Tobento\App\Seeding\AbstractFactory;

class UserFactory extends AbstractFactory
{
    protected function storeEntity(array $definition): object
    {
        return $this->getService(UserRepositoryInterface::class)
            ->create($definition);
    }
}
```

### Using Factories

[](#using-factories)

A factory can be created by calling the `new` method on the factory class:

```
$factory = UserFactory::new();

// you may overwrite the default definition:
$factory = UserFactory::new(['role' => 'editor']);
```

**Make entities**

The `make` method creates an array of entities and returns them for further use in code, but does not store them in the database e.g.

```
// make 10 entities:
$users = $factory->times(10)->make();

// make one:
$user = $factory->makeOne();
```

**Create entities**

The `create` method creates an array of entities, stores them in the database for instance and returns them for further use in the code.

```
// create 10 entities:
$users = $factory->times(10)->create();

// create one:
$user = $factory->createOne();
```

**Raw entities**

The `raw` method creates an array of attributes from definition only and returns them for further use in code.

```
// create 10:
$attributes = $factory->times(10)->raw();

// create one:
$attributes = $factory->rawOne();
```

**Modify definition**

You may modify the definition by using the `modify` method:

```
use Tobento\Service\Seeder\SeedInterface;

$users = $factory
    ->modify(fn (SeedInterface $seed, array $definition) => [
        'email' => $seed->email(),
    ])
    ->times(10)
    ->make();
```

You may use the method inside your factory class:

```
use Tobento\App\Seeding\AbstractFactory;
use Tobento\Service\Seeder\SeedInterface;

class UserFactory extends AbstractFactory
{
    public function withEmail(string $email): static
    {
        return $this->modify(fn(SeedInterface $seed, array $definition) => [
            'email' => $email
        ]);
    }
}

$users = $factory
    ->withEmail('admin@example.com')
    ->times(10)
    ->make();
```

**Modify entity**

You may modify the entity by using the `modifyEntity` method:

```
use Tobento\Service\Seeder\SeedInterface;

$users = $factory
    ->modifyEntity(static function (SeedInterface $seed, object $user) {
        return $user->markAsDeleted();
    })
    ->times(10)
    ->make();
```

You may use the method inside your factory class:

```
use Tobento\App\Seeding\AbstractFactory;
use Tobento\Service\Seeder\SeedInterface;

class UserFactory extends AbstractFactory
{
    public function deleted(string $email): static
    {
        return $this->modifyEntity(static function (SeedInterface $seed, object $user) {
            return $user->markAsDeleted();
        });
    }
}

$users = $factory
    ->deleted()
    ->times(10)
    ->make();
```

Seeders
-------

[](#seeders)

You may create a seeder class to easily seed your application with test data.

### Creating Seeders

[](#creating-seeders)

To create a seeder, create a class that implements the `SeederInterface::class`:

```
use Tobento\App\Seeding\SeederInterface;

class UserSeeder implements SeederInterface
{
    public function run(): \Generator
    {
        foreach (UserFactory::new()->times(100)->create() as $user) {
            yield $user;
        }
    }
}
```

If you want to seed millions of test data, using factories my not be the fastest solution. Instead you may directly use the storage if available which is much faster.

Example using the user repository from the [App User](https://github.com/tobento-ch/app-user) bundle:

```
use Tobento\App\Seeding\SeederInterface;
use Tobento\App\User\UserRepositoryInterface;
use Tobento\Service\Repository\Storage\StorageRepository;
use Tobento\Service\Iterable\ItemFactoryIterator;

class UserSeeder implements SeederInterface
{
    public function __construct(
        protected UserRepositoryInterface $userRepository,
    ) {
        if (! $userRepository instanceof StorageRepository) {
            throw new \InvalidArgumentException('Not supported ...');
        }
    }

    public function run(): \Generator
    {
        yield from $this->userRepository
            ->query()
            ->chunk(length: 10000)
            ->insertItems(new ItemFactoryIterator(
                factory: function (): array {
                    return UserFactory::new()->definition();
                },
                create: 1000000,
            ));
    }
}
```

### Adding Seeders

[](#adding-seeders)

You may add seeders to be run by the app console using the app `on` method.

```
use Tobento\App\Seeding\SeedersInterface;

// ...

$app->on(
    SeedersInterface::class,
    static function (SeedersInterface $seeders): void {
        $seeders->addSeeder('users', UserSeeder::class);
    }
);
```

### Running Seeders

[](#running-seeders)

To run your added seeders use the `seed` console command.

```
php ap seed
```

**Run only specific seeders by its name**

```
php ap seed --name=users
```

**Display seeded entities**

You may display the seeded entities with the verbosity option:

```
php ap seed -v
```

**List all seeder names**

You may display the seeder names by using the `seed:list` console command.

```
php ap seed:list
```

User Seeding
------------

[](#user-seeding)

If you have installed the [User App](https://github.com/tobento-ch/app-user) bundle you may use the provided user factory and user seeder.

**User Factory**

```
use Tobento\App\Seeding\User\UserFactory;

$user = UserFactory::new()
    ->withEmail('foo@example.com')
    ->withSmartphone('22334455')
    ->withUsername('Username')
    ->withPassword('123456')
    ->withRoleKey('admin') // 'guest' if role does not exist.
    ->withAddress(['firstname' => 'Firstname'])
    ->makeOne();
```

**User Seeder**

```
use Tobento\App\Seeding\User\UserStorageSeeder;

$app->on(
    SeedersInterface::class,
    static function (SeedersInterface $seeders): void {
        $seeders->addSeeder('users', UserStorageSeeder::class);
    }
);
```

Repository
----------

[](#repository)

You may easily create seed [factories](#factories) and [seeders](#seeders) from any repository implementing the [Repository Interface](https://github.com/tobento-ch/service-repository#repository-interface).

### Creating Repository Factories

[](#creating-repository-factories)

**Using the repository factory**

By using the `RepositoryFactory::new` method, you can quickly create a seed factory, which may be useful for testing purposes.

```
use Tobento\App\Seeding\Repository\RepositoryFactory;
use Tobento\Service\Repository\RepositoryInterface;
use Tobento\Service\Seeder\SeedInterface;
use Tobento\Service\Seeder\Lorem;

$factory = RepositoryFactory::new(
    repository: MyProductRepository::class, // string|RepositoryInterface
    definition: function (SeedInterface $seed): array {
        return [
            'sku' => Lorem::word(number: 1),
            'desc' => Lorem::sentence(number: 2),
        ];
    }
);

// using the factory:
$products = $factory->times(10)->make();
```

[Storage Repositories](https://github.com/tobento-ch/service-repository-storage) with defined [columns](https://github.com/tobento-ch/service-repository-storage#repository-with-columns), will create the definition automatically based on the columns. You do not need to set a definition at all.

```
use Tobento\App\Seeding\Repository\RepositoryFactory;

$factory = RepositoryFactory::new(repository: MyProductRepository::class);

// using the factory:
$products = $factory->times(10)->make();
```

Check out the [Using Factories](#using-factories) section for more info using the factory in general.

**Using the AbstractFactory**

To create a factory, create a class that extends the `AbstractFactory::class` and use the `REPOSITORY` constant to define your repository class:

```
use Tobento\App\Seeding\Repository\AbstractFactory;

class ProductFactory extends AbstractFactory
{
    public const REPOSITORY = MyProductRepository::class;
}

// using the factory:
$products = ProductFactory::new()->times(10)->make();
```

Sure, you may customize the definition for more flexibility:

```
use Tobento\App\Seeding\Repository\AbstractFactory;

class ProductFactory extends AbstractFactory
{
    public function definition(): array
    {
        // you may call the parent if you have
        // repositories with columns so it will
        // automatically create the definition
        // based on the columns.
        $definition = parent::definition();

        // and just overwrite if needed:
        $definition['name'] = $this->seed->firstname();

        return $definition;
    }
}
```

Credits
=======

[](#credits)

- [Tobias Strub](https://www.tobento.ch)
- [All Contributors](../../contributors)

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance58

Moderate activity, may be stable

Popularity11

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity64

Established project with proven stability

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

Total

6

Last Release

274d ago

Major Versions

1.x-dev → 2.02025-10-02

PHP version history (2 changes)1.0.0PHP &gt;=8.0

2.0PHP &gt;=8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/055d6a1b5c2384bb179c75ab0b55914231d898fdc4dffeb30770f81200e52206?d=identicon)[TOBENTOch](/maintainers/TOBENTOch)

---

Top Contributors

[![tobento-ch](https://avatars.githubusercontent.com/u/16684832?v=4)](https://github.com/tobento-ch "tobento-ch (11 commits)")

---

Tags

packageappseedingtobento

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tobento-app-seeding/health.svg)

```
[![Health](https://phpackages.com/badges/tobento-app-seeding/health.svg)](https://phpackages.com/packages/tobento-app-seeding)
```

PHPackages © 2026

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