如何在 Laravel 中实现自己的 Faker 提供者

How to implement your own Faker provider in Laravel

我想在 Laravel 中为 Faker 创建一个自定义提供程序(例如,一个用于随机建筑物名称的提供程序)。

我应该在我的应用程序中的什么地方存储自定义提供程序以及如何使用它?

您应该使用 php artisan 生成自定义提供程序...

在命令行中,导航至应用程序的根目录并键入...

php artisan make:provider FakerServiceProvider

这应该会在 app/Providers 文件夹中生成一个新的提供程序。这是我的 register 函数看起来像 faker 文档中的示例。

/**
 * 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;
    });
}

我在这里使用匿名 class。如果 php < 7,您可能需要使用新提供程序 class 创建一个新文件并将其传入。确保您还将此新提供程序添加到 providers 数组在 config/app.php.

现在它已注册,您可以使用以下方式获取您的新 faker class...

$faker = app('Faker');
echo $faker->title;

此外,如果您阅读 https://laravel.com/docs/5.2/facades 中的文档,您应该也可以很容易地制作 Faker 门面。所有繁重的工作都已完成,您只需创建新外观 class、getFacadeAccessor return 'Faker',并将其添加到您的 facades app/config.php.

中的数组

然后你就可以像这样简单地使用它...

echo Faker::title;

创建您的自定义提供程序 class 并将其保存在 app/Faker/CustomProvider.php 下。代码:

namespace App\Faker;

use Faker\Provider\Base;

class CustomProvider extends Base
{
    public function customName()
    {
        return $this->generator->sentence(rand(2, 6));
    }
}

然后你只需要通过 addProvider 方法将自定义提供程序添加到 faker。添加自定义提供程序的 laravel 工厂示例:

<?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,
    ];
});

我发现这个效果更好,因为它不需要用 resolve():

实例化我的 $faker 实例
public function register ()
    {
        $this->app->bind( Generator::class, function ( $app ) {

            $faker = \Faker\Factory::create();
            $faker->addProvider( new CustomFakerProvider( $faker ) );

            return $faker;
        } );

    }

最干净的方法是在 ServiceProvider class 中调用一个方法来检查是否安装了 Faker(它不应该在生产中),然后扩展核心定义。


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;
            });
        }
    }
}

如果你正在使用 Laravel 工厂,你可以像这样使用 withFaker 方法

/**
 * Get a new Faker instance.
 *
 * @return \Faker\Generator
 */
protected function withFaker()
{
    $faker = parent::withFaker();
    $faker->addProvider(new CustomProvider($faker));
    return $faker;
}

这会将提供程序添加到工厂正在使用的生成器实例中,因此它仅在您重载该方法的工厂中可用。