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

panthro's avatar

Adding a custom faker service provider?

I'm trying to add https://github.com/morawskim/faker-images to faker in Laravel.

I have a faker service provider...

<?php

namespace App\Providers;

use Faker\{Factory, Generator};
use Illuminate\Support\ServiceProvider;

class FakerServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Generator::class, function () {
            $faker = Factory::create();
            
            $faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
            
            return $faker;
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

This is conditionally loaded via the app service provider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        if (!$this->app->environment('production')) {
            $this->app->register('App\Providers\FakerServiceProvider');
        }
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

Yet, fake()->picsumUrl() gives the error Unknown format "picsumUrl".

I've checked and the faker service provider is ran. There is no issues with the package either as I can do the following and get an image url...

        $faker = \Faker\Factory::create('en_GB');
        $faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
        dd($faker->loremFacesUrl(1234));

So there must be something wrong with how the package is being added to faker.

0 likes
14 replies
Sinnbeck's avatar

Another way you could do it. I assume you only need it in testing? If so, you can just put this in your TestCase::setUp()

        $faker = app(Generator::class);
        $faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
        $faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
        $faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));

This works. I tested it

1 like
Sinnbeck's avatar

@panthro ok. Just move it to a service provider then? This also works

         if (!$this->app->environment('production')) {
            $faker = $this->app->make(Generator::class);
            $faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
        }
1 like
Sinnbeck's avatar

@panthro How are you using it then? Be aware that you cannot use it with fake() as that is bound differently

2 likes
panthro's avatar

@Sinnbeck it must be because of being used with fake() then causing the issues... as this works:

fake()->addProvider(new \Mmo\Faker\PicsumProvider(fake()));
 fake()->addProvider(new \Mmo\Faker\LoremSpaceProvider(fake()));
 fake()->addProvider(new \Mmo\Faker\LoremFacesProvider(fake()));  

Should it not be used like that then?

Should I add the providers as per my original post - but call faker differently? If so, how?

Currently I m doing fake()->loremFacesUrl(1234)

Sinnbeck's avatar

@panthro The thing is that fake() binds to Generator::$locale, not just Generator :)

This is the code in the source '`` function fake($locale = null) { if (app()->bound('config')) { $locale ??= app('config')->get('app.faker_locale'); }

    $locale ??= 'en_US';

    $abstract = \Faker\Generator::class.':'.$locale; //here it adds the locale to the binding

    if (! app()->bound($abstract)) {
        app()->singleton($abstract, fn () => \Faker\Factory::create($locale));
    }

    return app()->make($abstract);
}
2 likes
panthro's avatar

@Sinnbeck Ok, so I would need to bind it to Factory::create()?

If so, how would I use it across the app? Not use fake()-> but some other way?

Sinnbeck's avatar

@panthro you could bind it to fake() and just be sure to use that every where. Just be aware that you need to rebind if you use multiple locale

1 like
panthro's avatar

@Sinnbeck so if I binded to fake would I just do...

$faker = fake();
$faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
$faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
$faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));  

Would this not be added inside $this->app->singleton(Generator::class, function () {?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@panthro no need. just directly in the service provider

         if (!$this->app->environment('production')) {
            $faker = fake();
            $faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
            $faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
        }
1 like
cwhite's avatar

I just created a similar provider:

FakerServiceProvider

class FakerServiceProvider extends ServiceProvider
{
    public function register()
    {
        $locale = 'en_US';

        $abstract = Generator::class . ':' . $locale;

        $this->app->singleton($abstract, function () use ($locale) {
            $faker = Factory::create($locale);

            $faker->addProvider(new Gravatar($faker));
            $faker->addProvider(new PicsumPhotosProvider($faker));

            return $faker;
        });
    }

config/app.php

'providers' => [
    // ...
    App\Providers\FakerServiceProvider::class,
];
2 likes
olivsinz's avatar

@cwhite In case, you use others locales in your project, your code won't work. Here's a fix. $locale variable changed:

        $locale = app('config')->get('app.faker_locale') ?? 'en_US';

        $abstract = Generator::class . ':' . $locale;

        $this->app->singleton($abstract, function () use ($locale) {
            $faker = Factory::create($locale);

            $faker->addProvider(new Gravatar($faker));
            $faker->addProvider(new PicsumPhotosProvider($faker));

            return $faker;
        });
1 like

Please or to participate in this conversation.