FakerPHP/Faker 完整使用详解

FakerPHP/Faker 完整使用详解

FakerPHP/Faker 是 PHP 生态最流行的假数据生成库,是原fzaninotto/faker的官方维护分支(原包已停止更新)。它可以快速生成逼真的测试数据,完美适配单元测试、开发演示数据、数据库填充、压力测试等场景,支持全球几十种语言本地化,对中文环境有完整支持。

一、安装与环境要求

环境要求

  • 最新稳定版要求 PHP 7.4 及以上(支持 PHP 8.0+)
  • 必须通过 Composer 安装
  • 低 PHP 版本兼容:PHP 7.2-7.3 可安装fakerphp/faker:^1.17

安装命令

开发环境安装(推荐)

Faker 仅用于开发 / 测试场景,推荐安装到开发依赖中,生产环境不会自动加载:

composer require --dev fakerphp/faker

旧包迁移

如果你的项目之前使用已停止维护的fzaninotto/faker,先卸载旧包再安装新包,两者命名空间、API 完全兼容,业务代码无需修改:

composer remove fzaninotto/faker
composer require --dev fakerphp/faker

二、基础使用

核心初始化

<?php
// 引入Composer自动加载
require_once __DIR__ . '/vendor/autoload.php';

// 1. 默认英文环境实例化
// $faker = Faker\Factory::create();

// 2. 简体中文环境实例化(国内用户必用,生成中文数据)
$faker = Faker\Factory::create('zh_CN');

// 3. 繁体中文环境
// $faker = Faker\Factory::create('zh_TW');

// 生成基础假数据
echo $faker->name(); // 输出中文姓名,如 "张伟"
echo $faker->phoneNumber(); // 输出国内手机号,如 "13812345678"
echo $faker->address(); // 输出中文完整地址
?>

固定随机种子(可重复生成相同数据)

通过seed()设置随机数种子,每次运行都会生成完全相同的假数据,适合单元测试保证结果可复现:

$faker = Faker\Factory::create('zh_CN');
// 设置固定种子
$faker->seed(12345);

// 每次运行都会输出相同的姓名
echo $faker->name();

三、核心格式化器(Formatters)分类详解

格式化器是 Faker 生成假数据的核心方法,按使用场景分类如下,重点标注中文环境专属支持的方法:

个人信息类(最常用)

方法作用示例输出
name()生成完整中文姓名李娜、王强
firstName()生成中文名伟、芳
lastName()生成中文姓张、刘
title()生成称呼 / 头衔先生、女士、博士、工程师
gender()生成性别男、女
idNumber()【zh_CN 专属】生成合法 18 位身份证号110101199001011234
age($min=0, $max=100)生成指定范围的年龄28
birthday($max='now', $format='Y-m-d')生成生日1995-03-15
licensePlate()【zh_CN 专属】生成车牌号京 A12345

示例

// 生成完整个人信息
echo "姓名:" . $faker->name() . "\n";
echo "身份证号:" . $faker->idNumber() . "\n";
echo "性别:" . $faker->gender() . "\n";
echo "生日:" . $faker->birthday() . "\n";

地址类

方法作用示例输出
address()生成完整中文地址上海市浦东新区张江高科技园区博云路 2 号
province()【zh_CN 专属】生成省份广东省、四川省
city()【zh_CN 专属】生成城市深圳市、成都市
district()【zh_CN 专属】生成区县天河区、武侯区
streetAddress()生成详细街道地址中关村大街 1 号
postcode()生成邮政编码100080
latitude() / longitude()生成经纬度39.9042, 116.4074

通讯与互联网类

方法作用示例输出
phoneNumber()【zh_CN 专属】生成国内手机号13912345678
telNumber()【zh_CN 专属】生成固定电话010-87654321
email()生成邮箱地址zhangwei@example.com
safeEmail()生成安全测试邮箱(不会真实发送)li.na@example.org
freeEmail()生成免费邮箱wangqiang@163.com
username()生成用户名zhangwei1995
url()生成随机 URLhttps://www.example.com
domainName()生成域名example.com
ipv4() / ipv6()生成 IP 地址192.168.1.100
userAgent()生成浏览器 UAMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36…

文本与内容类

方法作用
sentence($nbWords=6)生成一句话
paragraph($nbSentences=3)生成一个段落
realText($maxNbChars=200)【推荐】基于真实中文语料生成逼真文本,比 text () 更自然
word() / words($nb=3)生成单个词 / 多个词
randomHtml()生成随机 HTML 片段

日期与时间类

方法作用
date($format='Y-m-d', $max='now')生成指定格式的日期
time($format='H:i:s')生成时间
dateTime($max='now')生成 DateTime 对象
dateTimeBetween($startDate, $endDate)生成指定区间的日期时间,最常用
dateTimeInInterval($startDate, $interval)生成指定间隔内的日期
unixTime()生成 Unix 时间戳

示例

// 生成最近1年的日期
echo $faker->dateTimeBetween('-1 year', 'now')->format('Y-m-d H:i:s');
// 生成未来30天的日期
echo $faker->dateTimeBetween('now', '+30 days')->format('Y-m-d');

数字与计算类

方法作用
numberBetween($min, $max)生成指定范围的整数
randomFloat($nbMaxDecimals, $min, $max)生成指定小数位数的浮点数(适合价格、金额)
boolean($chanceOfGettingTrue=50)生成布尔值,可指定为 true 的概率
randomDigit()生成 0-9 的随机数字
randomNumber($nbDigits)生成指定位数的随机数

示例

// 生成商品价格,0.01-999.99元,两位小数
echo $faker->randomFloat(2, 0.01, 999.99);
// 80%概率为true(模拟已发布状态)
echo $faker->boolean(80);

金融与支付类

方法作用
bank()【zh_CN 专属】生成国内银行名称
creditCardNumber()生成信用卡号
creditCardExpirationDate()生成信用卡有效期
iban()生成国际银行账号

图片与文件类

方法作用
imageUrl($width, $height, $category)生成占位图片 URL(基于 picsum.photos,无需下载)
image($dir, $width, $height)生成并下载占位图片到本地(需要网络连接)
mimeType()生成 MIME 类型
fileExtension()生成文件扩展名

其他常用方法

方法作用
uuid()生成 UUID
hexColor() / rgbCssColor()生成颜色值
randomElement($array)从数组中随机抽取一个元素
randomElements($array, $count)从数组中随机抽取多个元素
shuffle($array/$string)打乱数组 / 字符串
lexify($pattern)替换?为随机字母,如lexify('???')生成 3 位随机字母
numerify($pattern)替换#为随机数字,如numerify('####')生成 4 位随机数字

四、高级修饰符(Modifiers)

修饰符可以链式调用,给格式化器增加额外的规则,是提升开发效率的核心功能,常用的有 3 个:

unique():生成唯一不重复的数据

避免生成重复数据,解决数据库唯一键冲突问题,适合生成唯一邮箱、身份证号、手机号等。

// 生成10个不重复的邮箱
for ($i=0; $i<10; $i++) {
    echo $faker->unique()->email() . "\n";
}

// 生成不重复的身份证号
echo $faker->unique()->idNumber();

// 重置唯一性检查
$faker->unique($reset = true);

⚠️ 注意:如果生成数量超过该字段的可能范围,会抛出OverflowException异常,比如生成 100 个不重复的 0-9 的数字,需确保范围足够。

optional():生成可选数据(可空)

模拟非必填字段,有指定概率返回有效值,否则返回默认值(默认 null)。

// 50%概率返回地址,50%返回null
echo $faker->optional()->address();

// 30%概率返回手机号,70%返回null
echo $faker->optional($weight = 0.3)->phoneNumber();

// 自定义默认值,70%概率返回公司名,30%返回"无"
echo $faker->optional($weight = 0.7, $default = '无')->company();

valid():通过自定义规则过滤数据

通过回调函数验证,仅返回符合规则的数据,不满足则重新生成。

// 生成大于100的偶数
$faker->valid(function($value) {
    return $value > 100 && $value % 2 == 0;
})->numberBetween(1, 200);

// 生成仅以.com结尾的邮箱
$faker->valid(function($email) {
    return str_ends_with($email, '.com');
})->email();

默认最多重试 10000 次,可通过第二个参数自定义最大重试次数:valid($callback, $maxRetries = 20000)

五、自定义格式化器(自定义 Provider)

当默认格式化器无法满足需求时,可以自定义 Provider 扩展功能,比如生成订单号、商品 SKU、自定义分类等。

实现步骤

  • 创建自定义 Provider 类,继承Faker\Provider\Base
  • 在类中添加自定义方法(方法名即为格式化器名称)
  • 将自定义 Provider 注册到 Faker 实例
  • 像使用默认格式化器一样调用

完整示例

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Faker\Factory;
use Faker\Provider\Base;

// 自定义Provider
class CustomProvider extends Base
{
    /**
     * 生成订单号:ORDER + 年月日 + 6位随机数
     */
    public function orderNo()
    {
        return 'ORDER' . date('Ymd') . $this->generator->randomNumber(6, true);
    }

    /**
     * 生成商品SKU
     */
    public function productSku()
    {
        return strtoupper($this->generator->lexify('???')) . '-' . $this->generator->randomNumber(4, true);
    }

    /**
     * 生成商品分类
     */
    public function productCategory()
    {
        $categories = ['电子产品', '服装鞋帽', '食品生鲜', '家居用品', '美妆护肤', '运动户外'];
        return $this->randomElement($categories);
    }
}

// 实例化Faker
$faker = Factory::create('zh_CN');
// 注册自定义Provider
$faker->addProvider(new CustomProvider($faker));

// 使用自定义格式化器
echo "订单号:" . $faker->orderNo() . "\n";
echo "商品SKU:" . $faker->productSku() . "\n";
echo "商品分类:" . $faker->productCategory() . "\n";
?>

六、主流框架实战场景

场景 1:Laravel 模型工厂(内置支持)

Laravel 已内置 Faker,无需单独安装,是 Laravel 数据填充的标准方案。

步骤 1:配置中文环境

修改config/app.php,设置 Faker 本地化:

'faker_locale' => 'zh_CN',

步骤 2:创建模型工厂

示例:database/factories/ArticleFactory.php

<?php
namespace Database\Factories;

use App\Models\Article;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class ArticleFactory extends Factory
{
    protected $model = Article::class;

    public function definition()
    {
        $title = $this->faker->sentence(5);
        return [
            'title' => $title,
            'slug' => Str::slug($title),
            'content' => $this->faker->realText(2000),
            'user_id' => $this->faker->numberBetween(1, 10),
            'cate_id' => $this->faker->numberBetween(1, 5),
            'is_published' => $this->faker->boolean(80), // 80%概率已发布
            'published_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
            'view_count' => $this->faker->numberBetween(0, 10000),
        ];
    }
}

步骤 3:创建数据填充类

示例:database/seeders/ArticleSeeder.php

<?php
namespace Database\Seeders;

use App\Models\Article;
use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    public function run()
    {
        // 批量生成100篇文章
        Article::factory()->count(100)->create();
    }
}

步骤 4:执行填充

# 执行指定填充器
php artisan db:seed --class=ArticleSeeder

# 执行所有填充器
php artisan db:seed

场景 2:ThinkPHP 6/8 数据填充

步骤 1:安装 Faker

composer require --dev fakerphp/faker

步骤 2:创建填充类

示例:app/seeder/ArticleSeeder.php

<?php
namespace app\seeder;

use think\migration\Seeder;
use Faker\Factory;
use app\model\Article;

class ArticleSeeder extends Seeder
{
    public function run()
    {
        $faker = Factory::create('zh_CN');
        $data = [];

        // 生成50条数据
        for ($i=0; $i<50; $i++) {
            $data[] = [
                'title' => $faker->sentence(5),
                'content' => $faker->realText(1000),
                'user_id' => $faker->numberBetween(1, 5),
                'cate_id' => $faker->numberBetween(1, 4),
                'status' => $faker->boolean(70),
                'create_time' => $faker->dateTimeBetween('-6 months', 'now')->format('Y-m-d H:i:s'),
                'update_time' => $faker->dateTimeBetween('-3 months', 'now')->format('Y-m-d H:i:s'),
            ];
        }

        // 批量插入
        Article::insertAll($data);
    }
}

步骤 3:执行填充

php think seed:run ArticleSeeder

七、注意事项与常见问题