FakerPHP生成多地区姓名时如何去除称谓与后缀?
问题描述
我写了一段用FakerPHP生成多地区姓名列表的PHP脚本:
<?php require_once(__DIR__ . "/vendor/autoload.php"); $gen_num = filter_input(INPUT_GET, 'num2gen', FILTER_SANITIZE_NUMBER_INT, array('options' => array('default' => 30, 'min' => 10, 'max' => 300))); $faker_langs = ['da_DK', 'sv_SE', 'nb_NO', 'fr_FR', 'pl_PL', 'fi_FI', 'en_GB']; //'de_DE', $fakers = []; foreach ($faker_langs as $l) { $fakers[] = Faker\Factory::create($l); } for ($x = 0; $x < $gen_num; $x++) { $lang = rand(0, count($faker_langs) - 1); echo $fakers[$lang]->name() . "\n"; }
我需要生成无干扰的姓名用于验证,但德语、波兰语生成的姓名包含称谓(比如{{titleMale}}、{{suffix}}),会影响验证。对比丹麦语的姓名格式(仅包含名+姓/中间名+姓),德语的格式里混有带称谓的模板:
// 德语Person Provider示例 protected static $maleNameFormats = [ '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}-{{lastName}}', '{{titleMale}} {{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}} {{suffix}}', '{{titleMale}} {{firstNameMale}} {{lastName}} {{suffix}}', ];
请问能不能直接去掉这些带称谓的模板,还是必须继承对应地区的Provider并重写姓名格式属性?
回答
两种方案都能实现需求,但推荐用更规范的继承重写方式:
1. 直接修改Faker源码(不推荐)
你确实可以找到de_DE/Person.php和pl_PL/Person.php文件,删除包含{{titleMale}}、{{suffix}}的格式项。但这种方法弊端明显:
- 后续Faker版本更新时,你的修改会被覆盖,每次升级都要重复操作;
- 破坏了依赖包的原始结构,团队协作时其他成员需要同步修改,维护成本高。
2. 继承地区Provider并重写属性(推荐)
这是更专业、可维护的做法,无需改动源码,具体步骤如下:
示例:重写德语Person Provider
<?php namespace App\Faker\Provider; use Faker\Provider\de_DE\Person as BasePerson; class Person extends BasePerson { // 重写男性姓名格式,移除带称谓和后缀的项 protected static $maleNameFormats = [ '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}', '{{firstNameMale}} {{lastName}}-{{lastName}}', ]; // 同理重写女性姓名格式 protected static $femaleNameFormats = [ '{{firstNameFemale}} {{lastName}}', '{{firstNameFemale}} {{lastName}}', '{{firstNameFemale}} {{lastName}}', '{{firstNameFemale}} {{lastName}}', '{{firstNameFemale}} {{lastName}}-{{lastName}}', ]; }
注册自定义Provider到Faker实例
在你的生成脚本中,创建对应地区的Faker实例后,替换默认的Person Provider:
<?php require_once(__DIR__ . "/vendor/autoload.php"); $gen_num = filter_input(INPUT_GET, 'num2gen', FILTER_SANITIZE_NUMBER_INT, array('options' => array('default' => 30, 'min' => 10, 'max' => 300))); $faker_langs = ['da_DK', 'sv_SE', 'nb_NO', 'fr_FR', 'pl_PL', 'fi_FI', 'en_GB', 'de_DE']; $fakers = []; foreach ($faker_langs as $l) { $faker = Faker\Factory::create($l); // 对德语和波兰语替换为自定义Provider if ($l === 'de_DE') { $faker->addProvider(new \App\Faker\Provider\Person($faker)); } elseif ($l === 'pl_PL') { // 同理创建并注册波兰语的自定义Person Provider $faker->addProvider(new \App\Faker\Provider\pl_PL\Person($faker)); } $fakers[] = $faker; } for ($x = 0; $x < $gen_num; $x++) { $lang = rand(0, count($faker_langs) - 1); echo $fakers[$lang]->name() . "\n"; }
这种方式既保留了Faker的原始功能,又能自定义符合需求的姓名格式,且不受版本更新影响,是生产环境的最优选择。
内容的提问来源于stack exchange,提问作者JoSSte
相关产品推荐
相关产品推荐

