Get started with 33% off your first certification using code: 33OFFNEW

How to replace Laravel's Faker default image provider

4 min read
Published on 26th April 2023

Faker is a popular PHP library used to generate fake data for testing purposes. In Laravel, Faker is integrated with the framework and used for seeding databases and testing factories. By default, Faker's image provider generates placeholder images using the Placeholder.com service.

The choice to use placeholder.com as the default service seems a strange one. The main website is not related to web development, and the subdomain (via.placeholder.com) which serves the images has no website or docs. It looks like the domain has been purchased by a warehouse rental firm. The original service did its job but wasn't great for producing images beyond grey squares.

So, you might want to swap the default image provider for another provider like PlaceKitten, PlaceImg, or a custom provider. In this article, we'll show you how to swap out the default image provider for Faker in Laravel.

Section 1: Understanding Laravel's Faker Integration and setup

Before diving into swapping the image provider, let's understand how Laravel integrates with Faker. Under the hood Laravel uses its own service provider to load an instance of Faker. In this tutorial we effectively need to write our own service provider and tell Laravel to use ours instead of theirs. Fortunately this is quite easy to do.

Please note: Laravel offers a convenient fake() helper which gives access to an instance of Faker. However, in our testing this is a standalone instance that isn't overridden by our service provider. Instead, in your factories, you should user $this->faker to access the correct faker instance.

The service provider is pretty simple and looks something like this:

public function register()
{
    $this->app->singleton(FakerGenerator::class, function () {
        return FakerFactory::create();
    });
}

It's always good to get an understanding of what the framework is doing behind the scenes before diving in.

Section 2: Extending the FakerServiceProvider

To swap out the default image provider, we need to extend the FakerServiceProvider and customize the creation of the Faker instance. First, create a new file in the app\Providers directory called CustomFakerServiceProvider.php:

php artisan make:provider CustomFakerServiceProvider

In this file we'll extend the ServiceProvider class, then override the register method and create a new instance of the Faker generator with the custom image provider.

<?php

namespace App\Providers;

use Faker\Factory as FakerFactory;
use Faker\Generator as FakerGenerator;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;

class CustomFakerServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(FakerGenerator::class, function () {
            // Create a new Faker instance with your custom image provider
            $faker = FakerFactory::create();

            // Swap the default image provider here
            // ...

            return $faker;
        });

        $this->app->singleton(EloquentFactory::class, function ($app) {
            return EloquentFactory::construct(
                $app->make(FakerGenerator::class), $this->app->databasePath('factories')
            );
        });
    }
}

Section 3: Implementing a Custom Image Provider

Now that we have extended the Faker ServiceProvider, let's implement a custom image provider. In this example, we'll use the PlaceKitten service as our image provider. Create a new directory called Faker in the app directory and create a new file called PlaceKittenProvider.php (app/Faker/PlaceKittenProvider.php).

Please note: You can place this file anywhere that is appropriately namespaced, but we like to keep all of our Faker classes together.

<?php

namespace App\Faker;

class PlaceKittenProvider
{
    public function imageUrl($width = 640, $height = 480)
    {
        return sprintf('https://placekitten.com/%d/%d', $width, $height);
    }
}

This should be pretty self-explanatory. Most image providers have a basic URL structure like this. It's entirely possible to build something far more complex here if you needed to, such as a provider that uses Unsplash's API to search for images specific to your app. Let's say, for example, that you run a gardening blog, you could create an image provider that searches for images related to 'garden' from their API and then resize them appropriately. Doing this would add an element of authenticity to your app during testing and development.

Section 4: Swapping the Image Provider

Now that we have our custom image provider, we need to swap it with the default provider in our CustomFakerServiceProvider. Update the register method to add our custom provider to the Faker instance.

public function register()
{
    $this->app->singleton(FakerGenerator::class, function () {
        $faker = FakerFactory::create();

        // Swap the default image provider
        $faker->addProvider(new \App\Faker\PlaceKittenProvider($faker));

        return $faker;
    });

    // ...
}

(optional) Section 5: Add the provider to your config

If you're using older versions of Laravel that don't support auto-discovery of providers then you'll need to add an entry to your config/app.php file in the providers array:

'providers' => [

    // ...

    // Add our custom provider
    App\Providers\CustomFakerServiceProvider::class,

    // ...

],

This is only really applicable in older versions of Laravel prior to version 5.1.

## All done!

That's it! Now, when you use Faker in your Laravel application, it will utilize the PlaceKitten image provider instead of the default placeholder.com provider. This method can be used to swap out the default image provider for any other provider, including custom ones tailored to your specific needs.

Take it for a spin in a factory:

// ...
$this->faker->imageUrl(600, 300); // https://placekitten.com/600/300
// ...

Remember that swapping out the default image provider might affect the behaviour of your tests and seeders. Always ensure that your tests and seeders continue to work as expected after making these changes.