How to implement your own Faker provider in Laravel
The cleanest way to do this is to call a method in a ServiceProvider
class that check if Faker is installed (it should not be in production), then extends the core definition.
use Faker\Generator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
// other stuff ...
$this->registerFaker();
}
private function registerFaker()
{
if (class_exists(Generator::class)) {
$this->app->extend(Generator::class, function (Generator $generator, $app) {
$generator->addProvider(new MyCustomProvider($generator));
return $generator;
});
}
}
}
You should use php artisan
to generate the custom provider...
On the command line, navigate to the root of your app and type...
php artisan make:provider FakerServiceProvider
That should generate a new provider in the app/Providers
folder. Here is what my register function looks like going off the example in the faker docs.
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton('Faker', function($app) {
$faker = \Faker\Factory::create();
$newClass = new class($faker) extends \Faker\Provider\Base {
public function title($nbWords = 5)
{
$sentence = $this->generator->sentence($nbWords);
return substr($sentence, 0, strlen($sentence) - 1);
}
};
$faker->addProvider($newClass);
return $faker;
});
}
I'm using an anonymous class here. If you have php < 7, you would likely need to create a new file with your new provider class and pass that in. Make sure you also add this new provider to your providers
array in config/app.php
.
Now that it's registered, you can grab your new faker class using the following...
$faker = app('Faker');
echo $faker->title;
Additionally, if you go through the docs at https://laravel.com/docs/5.2/facades you should also be able to make a Faker
facade quite easily. All the heavy lifting is done, you'd just have to create the new facade class, have getFacadeAccessor
return 'Faker'
, and add it to your facades
array in app/config.php
.
Then you can simply use it like so...
echo Faker::title;
Create your custom provider class and save it under app/Faker/CustomProvider.php. Code:
namespace App\Faker;
use Faker\Provider\Base;
class CustomProvider extends Base
{
public function customName()
{
return $this->generator->sentence(rand(2, 6));
}
}
Then you need just add your custom provider to faker by addProvider method. Example of laravel's factory with adding custom provider:
<?php
use Faker\Generator as Faker;
$factory->define(App\Models\Model::class, function(Faker $faker) {
$faker->addProvider(new App\Faker\CustomProvider($faker));
return [
'name' => $faker->customName,
];
});
I found this worked better, as it did not require my $faker
instance to be instantiated with resolve()
:
public function register ()
{
$this->app->bind( Generator::class, function ( $app ) {
$faker = \Faker\Factory::create();
$faker->addProvider( new CustomFakerProvider( $faker ) );
return $faker;
} );
}