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

Danaq's avatar
Level 1

Laravel calling seeder in subdirectory - Class not found

Laravel (currently 8.12 | php 7.4.14) started throwing errors a few days ago when I try to execute a seeder in a subdirectory via Artisan::call.

On bash this command works fine:

php artisan db:seed --class=Database\Seeders\Testing\StagingTestDataSeeder

But I want to execute it as:

Artisan::call("db:seed --class=Database\Seeders\Testing\StagingTestDataSeeder");

The result is: Target class [Database\\Seeders\\DatabaseSeedersTestingStagingTestDataSeeder] does not exist. Which is absolutely correct as there are no namespace delimiters in the argument. Beacuse there are no delimiters in the argument, the getSeeder-method just concats the argument to the base namespace of database seeders (see below if (strpos($class, '\\') === false) {).

Because it works on bash I don't thinkt that there are any mistakes with namespace or file location. I dumped some data in the Illuminate\Database\Console\Seeds\SeedCommand.php::66

/**
     * Get a seeder instance from the container.
     *
     * @return \Illuminate\Database\Seeder
     */
    protected function getSeeder()
    {
        $class = $this->input->getArgument('class') ?? $this->input->getOption('class');
        dump($this->options());
        dump($this->arguments());
        dump($class);
        if (strpos($class, '\') === false) {
            $class = 'Database\Seeders\' . $class;
        }

        if (
            $class === 'Database\Seeders\DatabaseSeeder' &&
            !class_exists($class)
        ) {
            $class = 'DatabaseSeeder';
        }

        return $this->laravel->make($class)
            ->setContainer($this->laravel)
            ->setCommand($this);
    }

which prints this:

array:10 [▼
  "class" => "DatabaseSeedersTestingStagingTestDataSeeder"
  "database" => null
  "force" => false
  "help" => false
  "quiet" => false
  "verbose" => false
  "version" => false
  "ansi" => null
  "no-interaction" => false
  "env" => null
]
array:2 [▼
  "command" => "db:seed"
  "class" => null
]
"DatabaseSeedersTestingStagingTestDataSeeder"

Somehow the escaped backslash does not reach the getSeeder-method of the SeedCommand-class. I know that I could load the class with pure PHP via require or add the deep namespace to the composer.json. But as this is not the intended use by laravel I want to figure out how to do it with onboard functionality.

---- a few tests later ----

I figured out that I can pass the class/ namespace value as option (with --class=) as well as argument (just the namespace) to the SeedCommand.php. So Artisan::call("db:seed Database\\\\Seeders\\\\Testing\\\\StagingTestDataSeeder"); works now.

Also, there is another method according to the documentation by passing the argument as array: Artisan::call('db:seed', ['--class=' => 'Database\Seeders\Testing\StagingTestDataSeeder']);

Can someone explain what happens there? I'm totally confused why I need to pass the double amount of backslashes. It seems that the argument is interpreted twice or something. Until today I was always able to use the same syntax for the bash command as well as for the Artisan::call()-call. Was the SeedCommand recently updated?

0 likes
3 replies
Nakov's avatar

Have you tried this syntax?

Artisan::call('db:seed', [
    '--class' => 'Database\Seeders\Testing\StagingTestDataSeeder'
]);

or

Artisan::call('db:seed', [
    '--class' => StagingTestDataSeeder::class
]);

with an import at the top of your class of course?

Danaq's avatar
Level 1

@Nakov yeah, as I wrote in the second last paragraph, this works now. But the question was, why the syntax I used before stoped working.

Nakov's avatar

@Danaq sorry didn't saw that on your initial comment, so probably you edited after I posted, but anyway.. different OS interprets the \ differently, so those need to be escaped. I would use the ::class syntax much better and you don't have to worry about the slashes.

Please or to participate in this conversation.