Database Seeders

Table of contents

  1. Overview
  2. Creating a Seeder Class
  3. Setting Up the Seeder Class
  4. Setting Up the DatabaseSeeder Class
  5. Running a Database Seeder
  6. Seeder Tips and Best Practices


1. Overview Table of Contents

This framework supports the ability to seed a database with fake data utilizing a package called FakerPHP. Consult their documentation here for more information about what they support. Using this package, along with the native support for Seeder classes you are able to populate tables in your database with test seeder data. The list of third-party libraries can be found here.


2. Creating a Seeder Class Table of Contents

You can easily create a new database seeder by running the make:seeder console command. This command has the following format:

php console make:seeder ${seederName}

Use the optional --factory flag to generate a factory with this seeder.

The seederName is the name of your model and the table you want to populate with data. We will use the Contact management system as an example. Running the following command,

php console make:seeder Contacts

will result in a new file called ContactsTableSeeder being created at database/seeders/. The resulting template file is shown below.

namespace Database\Seeders;

use Core\Lib\Database\Seeder;
use Database\Factories\ContactsFactory;

/**
 * Seeder for contacts table.
 * 
 * @return void
 */
class ContactsTableSeeder extends Seeder {
    /**
     * Runs the database seeder
     *
     * @return void
     */
    public function run(): void {

    }
}

This file contains the run function that does the actual work and all of the imports needed to get started.

Each seeder you create must be registered in the run function in the DatabaseSeeder class. You can use the call function to run seeders individually or as an array.

As Strings

public function run(): void {
    $this->call(UsersTableSeeder::class);
    $this->call(ProfileImageTableSeeder::class);
}

As an Array

public function run(): void {
    $this->call([
        UsersTableSeeder::class, 
        ProfileImageTableSeeder::class
    ]);
}


3. Setting up The Seeder Class Table of Contents

We will focus on the following code for a completed run function.

public function run(): void {
    $factory = new ContactsFactory(1);
    $factory->count(5)->create();
    console_info("Seeded contacts table.");
}

You will create a new factory and set the parameter in call to the constructor. Use the count function to generate new records. It takes 1 parameter for the number of records to create.

You can also use the static factory function. The factory function accepts the spread parameter so you can supply the user_id described in the guide for Factories:

ContactsFactory::factory(1)->count(5)->create();


4. Setting Up the DatabaseSeeder Class Table of Contents

Before we can run the database seeder we need to update the DatabaseSeeder class. It is found in the same directory as the class that we created above. You will need to perform the imports and add the function calls in the order you want database seeding to occur. A properly setup example is shown below:

namespace Database\Seeders;

use Core\Lib\Database\Seeder;
use Database\Seeders\ContactsTableSeeder;

/**
 * Supports ability to call seeder classes.
 */
class DatabaseSeeder extends Seeder {
    /**
     * Call individual seeders in proper order.
     *
     * @return void
     */
    public function run(): void {
        $this->call(ContactsTableSeeder::class);
    }
}

Notice that we need to include a use statements for each seeder we want to use. Within the run function is a call to the call function of the Seeder class. This is where the mechanics of database seeding operations occurs.


5. Running a Database Seeder Table of Contents

We are finally ready to perform database seeding. Let’s look at the index view of the contacts management system before we start.

Contacts' index view with no data

Figure 1 - Contacts' index view with no data

As shown above in Figure 1 we have the index view with no seeders. Since the Contacts Management System is a testbed for testing development efforts we will want to populate this page with dummy data. Let’s suppose we want to test pagination so we will want to create 20 records. Run the command below to seed the contacts table.

php console seed:run

You can also specify a specific seeder class to run with the --seeder flag as shown below:

php console seed:run --seeder=UsersTableSeeder

After running the command you will see a series of messages describing our task as shown below in Figure 2.

Database seeding console output

Figure 2 - Database seeding console output

Finally, upon inspection of the Contacts’ index we will see that the database has been seeded with 20 entries. Thus, we can go ahead and test the pagination feature. The example view is shown below in Figure 3.

Contacts' index view after seeder operation

Figure 3 - Contacts' index view after seeder operation

But viewing the Contacts’ index view is just one phase of our testing. We need to click the links for a few of our contacts to make sure the contact information card has the information we expect. Let’s click on the link for our contact, Carmel Leannon, to see their details.

Carmel Leannon's contact information

Figure 4 - Carmel Leannon's contact information

As shown above in Figure 4, we can see that Carmel’s information looks like we would expect. It contains a valid street address along with a city, state, and zip code that matches USPS standards. The first name and last name makes sense despite it being completely made up. Finally, the email and phone number matches a valid format.

⚠️ Note: This command is safe for development/staging only. Avoid using in production unless you’re seeding static reference data.


6. Seeder Tips and Best Practices Table of Contents

  • ✅ Use seeders only in development or staging.
  • 🔗 Use foreign key-safe references (user_id = 1) that exist.
  • 🧠 Use Faker::unique() sparingly to avoid memory overuse.
  • 🧪 Chain multiple seeders in DatabaseSeeder to mirror real-world data order.
  • ❌ Avoid using seeders in production unless seeding static or required data (e.g., ACLs, roles).
  • 🔄 If using soft deletes, manually set deleted = 0 where needed.
  • 🧰 Keep each table’s seeder separate for modularity and easier maintenance.