Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

pekkagaiser's avatar

Where would you put importer classes in a Laravel project?

Getting started with Laravel and Backpack, building a web app that I'm migrating from an old PHP codebase.

Part of the migration is importing several tables full of data (bookings, users, bookable items) from the old application.

I have a Laravel class for each import task (BookingsImport, UsersImport, ItemsImport) that fetch the data from the old web site and for each table row create a new entry using the correct Laravel model (Booking::create, User::create, Item::create). The import classes also take care of new field names and necessary data transformations to make things work in the new Laravel app.

From a design perspective, where would you put these importer classes?

I suppose technically they belong in the custom Backpack controller I'm using to start the import. But that feels... wrong. The controller is there to dispatch the action, not to contain too much logic, right? Having it in the Laravel models feels wrong, too.

Am I supposed to simply create a new folder, say, "Importers" in the "App" folder? I can do that, but if there is a Laravel-y standard, I'd much rather follow that.

0 likes
2 replies
webrobert's avatar

Hmmm. old fall back is just a Services directory. You could just call them via a seeder class

I’ve kept these things in the database directory. Seeders are there. Factory’s too. I’ve added data folder for example. It seem relevant to me. It’s where I need it.

https://laravel.com/docs/9.x/seeding#main-content

1 like
webrobert's avatar
Level 51

example seeder

class InstrumentSeeder extends Seeder
{
    public function run()
    {
        // columns: id, symbol, name, exchange, description, type
        $csvFile    = fopen(base_path("database/data/stocks_with_weekly_options.csv"), "r");
        $firstline  = true;

        while (($data = fgetcsv($csvFile, 2000, ",")) !== FALSE) {

            if (!$firstline) {
                Instrument::create([
                    'symbol'      => $data['1'],
                    'name'        => $data['2'],
                    'exchange'    => $data['3'],
                    'description' => $data['4'],
                    'type'        => $data['5'],
                ]);
            }

            $firstline = false;
        }

        fclose($csvFile);
    }
}

I know another school of thought is to put the import in the migration. This just doesn't feel right to me. I think mainly because I want the system to be malleable and separate from the data during the initial development. I will tear down migrations or add to them vs making new ones to add columns.

1 like

Please or to participate in this conversation.