当前位置: 首页 > 后端技术 > PHP

Faker虚拟数据填充和源解析

时间:2023-03-29 20:02:31 PHP

Faker是一个虚拟数据生成器,可用于填充数据库以进行压力测试或创建优雅的XML文档。安装如果项目支持composer,使用如下命令安装。如果不支持,请从Faker的Github仓库下载源码,放在项目的扩展包文件夹中。composerrequirefzaninotto/faker为了演示功能,我新建了一个项目,命令如下://新建项目文件夹mkdirdata-seedercddata-seeder//安装faker扩展composerrequirefzaninotto/faker中的基本用法根目录创建一个测试文件test.php,输入如下代码:name,"\n";echo$faker->address,"\n";echo$faker->text;在CLI模式下运行脚本phptest.php以查看输出。faker的结果是随机生成的:Prof.KailynBarton9230HerzogGrovesSuite005Gusikowskihaven,CO60533-4716Nesciuntvoluptasdebitisiustoconsecteturpossimusmollitiainquam。Velnonremtemporibusillonumquamest.Sitfugitsedfugitideligendieaquesuntpossimus.faker的专有名词faker中定义了一些专有名词,帮助我们理解它的设计思想。理解这些概念对于理解他的源码很有帮助。Formatters(格式化程序)除了上述三个属性外,faker还提供了大量可供选择的模拟数据。每个生成器属性(例如上面使用的名称、地址和lorem)都称为格式化程序。Providers:我们需要填写的数据类型很多,比如基本的随机数据:整数、浮点数、字母随机字符信息:名字、姓氏、名字等随机数:手机号码、电话号码Faker把每个分类定义为provider。查看data-seeder/vendor/fzaninotto/faker/src/Faker/Provider可以看到各个provider的类文件和语言包的文件。源码分析faker扩展包体积小,五脏俱全,非常有学习价值。faker对象生成查看faker生成器的工厂方法:constDEFAULT_LOCALE='en_US';protectedstatic$defaultProviders=array('Address','Barcode','Biased','Color','Company','DateTime','File','HtmlLorem','Image','Internet','Lorem','杂项','付款','人','电话号码','文本','UserAgent','Uuid');publicstaticfunctioncreate($locale=self::DEFAULT_LOCALE){$generator=newGenerator();foreach(static::$defaultProvidersas$provider){$providerClassName=self::getProviderClassname($provider,$locale);$generator->addProvider(new$providerClassName($generator));}return$generator;}参数locale为语言包,默认为en_US美式英语。所有支持的语言包都可以在data-seeder/vendor/fzaninotto/faker/src/Faker/Provider目录下查看。在上面的Provider目录下可以一一找到默认的provider(上面已经提到provider)。循环遍历数组,将相应的提供者添加到生成器$generator中。getProviderClassname受保护的静态函数getProviderClassname($provider,$locale=''){if($providerClass=self::findProviderClassname($provider,$locale)){return$providerClass;}//回退到默认语言环境if($providerClass=self::findProviderClassname($provider,static::DEFAULT_LOCALE)){return$providerClass;}//回退到无语言环境if($providerClass=self::findProviderClassname($provider)){return$providerClass;}thrownew\InvalidArgumentException(sprintf('Unabletofindprovider"%s"withlocale"%s"',$provider,$locale));}getProviderClassname将根据以下逻辑搜索提供程序类,如果是当前文件不存在,进入下一级文件查找,如果没有找到,会抛出异常:用户传入的语言包文件夹->默认en_US语言包文件夹->Provider根目录addProviderpublicfunctionaddProvider($provider){array_unshift($this->providers,$provider);}addProvider很简单,将找到的provider添加到数组头部即可,数组存储在$generator对象的属性中被退回。在使用faker返回的对象时调用faker对象有两种方式:调用属性和调用方法。这些调用都会触发魔法方法:publicfunctionformat($formatter,$arguments=array()){returncall_user_func_array($this->getFormatter($formatter),$arguments);}publicfunction__get($attribute){return$this->format($attribute);}publicfunction__call($method,$attributes){return$this->format($method,$attributes);}两者逻辑类似,这里给出一个比较麻烦的__callmagicmethod,magicmethod会将调用的方法名和参数传给farmat方法。getFormatter公共函数getFormatter($formatter){if(isset($this->formatters[$formatter])){return$this->formatters[$formatter];}foreach($this->providersas$provider){if(method_exists($provider,$formatter)){$this->formatters[$formatter]=array($provider,$formatter);返回$this->formatters[$formatter];}}thrownew\InvalidArgumentException(sprintf('Unknownformatter"%s"',$formatter));}$this->formatters存储了faker专有名词中提到的格式化程序(formatter)相关的信息。为了方便理解,这里以数组中的随机元素为例来说明这些抽象概念。$faker->randomElement(['a','b','c']);当调用这个方法时,会触发魔术方法,然后遍历每个provider类,查找是否存在这个方法。直到在Base.php中找到这个方法,此时要使用的provider是Base.php,formatter是randomElement()方法。那么需要将randomElement()的对应关系存储在Base中,避免下次重新遍历所有provider,这就是$this->formatters实现的原因。该方法返回对应的provider和formatters后,通过call_user_func_array调用并返回结果。至此,一个完整的faker对象的生成和调用过程就结束了。