manguithre / faker-madagascar
Localized fake data generator for Madagascar, inspired by FakerPHP.
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/validation: ^11.0|^12.0|^13.0
Requires (Dev)
- fakerphp/faker: ^1.21
- friendsofphp/php-cs-fixer: ^3.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0|^5.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0|^4.0|^5.0
Suggests
- fakerphp/faker: Required to expose the malagasy* methods on Faker's Generator (^1.21).
Provides
None
Conflicts
None
Replaces
None
README
Generate realistic Madagascar-specific test data for Laravel and PHP applications.
Faker Madagascar provides Malagasy names, structured geographical addresses, operator-aware mobile phone numbers and CIN-formatted values.
The package includes:
- 23 regions.
- 119 districts.
- 1,704 communes.
- 20,688 fokontany names.
If you already know FakerPHP's fake() helper, you can start using this
package immediately.
Generated data is intended for development, testing and database seeding. It does not represent real individuals or officially issued documents.
Features
- Malagasy first names, last names and full names.
- Hierarchical addresses: region, district, commune and fokontany.
- 23 regions, 119 districts, 1,704 communes and 20,688 fokontany names.
- Malagasy mobile numbers using supported operator prefixes.
- CIN-formatted values with 12 digits.
- Laravel validation rules for phone numbers and CIN values.
- Laravel factories and seeders integration.
- FakerPHP integration through
fake()->malagasy*(). - Artisan preview command.
- JSON and CSV export.
- Region filtering through configuration.
- Standalone PHP support without Laravel.
- Case-insensitive region lookup.
Requirements
- PHP 8.2 or higher.
- Laravel 11, 12 or 13.
- FakerPHP
^1.21only if you want to use thefake()->malagasy*()integration.
In a standard Laravel application, FakerPHP is usually already installed.
Installation
Install the package with Composer:
composer require manguithre/faker-madagascar
The service provider and the FakerMg facade alias are registered through
Laravel package discovery. No manual registration is required.
The fakerMg() helper is available immediately after installation.
Quick start
After installing the package, use the fakerMg() helper anywhere in your
Laravel application:
$address = fakerMg()->address(); echo (string) $address; // Alakamisy Fenoarivo, Antananarivo Atsimondrano, ANALAMANGA, Ankadivory echo fakerMg()->fullName(); // Hery Rakotomalala echo fakerMg()->phoneNumber(); // 0321234567 echo fakerMg()->cin(); // 123456789012
Usage styles
All usage styles resolve to the same Faker Madagascar service inside Laravel.
Using the fakerMg() helper
The helper is the recommended usage style:
fakerMg()->address(); fakerMg()->region(); // ANALAMANGA fakerMg()->firstName(); // Hery fakerMg()->lastName(); // Rakotomalala fakerMg()->fullName(); // Hery Rakotomalala fakerMg()->phoneNumber(); // 0321234567 fakerMg()->phoneNumber('telma'); // 0341234567 fakerMg()->cin(); // 123456789012
The helper works in:
- Routes.
- Controllers.
- Models and factories.
- Seeders.
- Artisan commands.
- Tinker.
- Console applications.
Using the facade
use Manguithre\FakerMadagascar\Facades\FakerMg; FakerMg::address(); FakerMg::phoneNumber(); FakerMg::fullName();
Laravel registers the facade alias automatically when package discovery is enabled.
Using dependency injection
use Manguithre\FakerMadagascar\FakerMadagascar; public function run(FakerMadagascar $faker): void { $address = $faker->address(region: 'Atsinanana'); dump($address); }
Using FakerPHP
If FakerPHP is installed, the package registers a provider on Laravel's Faker generator. This allows you to mix standard FakerPHP data with Madagascar-specific data in the same call chain:
fake()->name(); fake()->malagasyFullName(); fake()->malagasyAddress(); fake()->malagasyPhoneNumber(); fake()->malagasyCin();
Note: The
malagasy*()methods are available when Faker's generator is resolved through Laravel's container, for example withfake()orapp(Faker\Generator::class). A generator created directly withFaker\Factory::create()does not automatically include this provider.
Example:
use Faker\Generator; $faker = app(Generator::class); $faker->malagasyFullName(); $faker->malagasyAddress();
API reference
| Method | Description | Return value |
|---|---|---|
address() |
Generates a random hierarchical address. | MalagasyAddress |
address(region: ...) |
Generates an address inside a specific region. | MalagasyAddress |
addressInDistrict($region, $district) |
Generates an address inside a district. | MalagasyAddress |
addressInCommune($region, $district, $commune) |
Generates an address inside a commune. | MalagasyAddress |
region() |
Returns a random region. | string |
regions() |
Returns all region names. | array |
districts($region) |
Lists the districts of a region. | array |
district($region) |
Returns a random district in a region. | string |
communes($region, $district) |
Lists the communes of a district. | array |
commune($region, $district) |
Returns a random commune in a district. | string |
fokontany($region, $district, $commune) |
Returns a random fokontany in a commune. | string |
firstName() |
Generates a Malagasy first name. | string |
lastName() |
Generates a Malagasy last name. | string |
fullName() |
Generates a Malagasy full name. | string |
phoneNumber($operator = null) |
Generates a Malagasy mobile number. | string |
phonePrefixes() |
Returns the supported mobile prefixes. | array |
cin() |
Generates a 12-digit CIN-formatted value. | string |
Return types shown above should match the actual public API of the installed package version.
Generating addresses
Random address
$address = fakerMg()->address(); echo $address->region; // ANALAMANGA echo $address->district; // Antananarivo Atsimondrano echo $address->commune; // Alakamisy Fenoarivo echo $address->fokontany; // Ankadivory
The address object can be converted to a string:
echo (string) $address; // Alakamisy Fenoarivo, Antananarivo Atsimondrano, ANALAMANGA, Ankadivory
It can also be converted to an array:
print_r($address->toArray());
Force a region
$address = fakerMg()->address(region: 'Atsinanana');
The district, commune and fokontany are selected consistently from the specified region.
Region names are case-insensitive:
fakerMg()->address(region: 'Analamanga'); fakerMg()->address(region: 'analamanga'); fakerMg()->address(region: 'ANALAMANGA');
These values refer to the same region.
Force a district
$address = fakerMg()->addressInDistrict( 'ANALAMANGA', 'Antananarivo Atsimondrano' );
Force a commune
$address = fakerMg()->addressInCommune( 'ANALAMANGA', 'Antananarivo Atsimondrano', 'Alakamisy Fenoarivo' );
Region names are resolved case-insensitively. District and commune names must match the names available in the dataset.
For example:
'Antananarivo Atsimondrano'
is valid, while this value may not be valid if exact matching is required:
'antananarivo atsimondrano'
Unknown regions, districts or communes throw:
Manguithre\FakerMadagascar\Exceptions\InvalidArgumentException
Browse the geographical hierarchy
fakerMg()->region(); // ANALAMANGA
fakerMg()->districts('ANALAMANGA'); // List of districts
fakerMg()->district('ANALAMANGA'); // One random district
fakerMg()->communes( 'ANALAMANGA', 'Antananarivo Atsimondrano' ); // List of communes
fakerMg()->commune( 'ANALAMANGA', 'Antananarivo Atsimondrano' ); // One random commune
fakerMg()->fokontany( 'ANALAMANGA', 'Antananarivo Atsimondrano', 'Alakamisy Fenoarivo' ); // One random fokontany
Address object
The address() method returns a structured address object.
Typical properties:
$address->region; $address->district; $address->commune; $address->fokontany;
Convert the object to an array:
$data = $address->toArray();
Convert the object to a formatted string:
$text = (string) $address;
The formatted string follows this structure:
commune, district, region, fokontany
Generating names
fakerMg()->firstName(); // Hery fakerMg()->lastName(); // Rakotomalala fakerMg()->fullName(); // Hery Rakotomalala
Names are generated from curated Malagasy name lists. They are intended to look natural for testing and development purposes.
Generated names are not guaranteed to correspond to real people.
Generating contact data
Phone numbers
fakerMg()->phoneNumber(); // 0321234567
You can optionally select an operator:
fakerMg()->phoneNumber('airtel'); // 0331234567 or 0351234567 fakerMg()->phoneNumber('telma'); // 0341234567 or 0381234567 fakerMg()->phoneNumber('orange'); // 0321234567 or 0371234567 fakerMg()->phoneNumber('bip'); // 0391234567
Supported prefixes:
fakerMg()->phonePrefixes(); // ['032', '033', '034', '035', '037', '038', '039']
The currently supported prefixes are:
| Prefixes | Operator |
|---|---|
032, 037 |
Orange |
033, 035 |
Airtel |
034, 038 |
Telma / Yas |
039 |
Bip |
Phone prefixes were checked against the ARTEC national numbering plan, international numbering tables and available operator announcements.
The prefix dataset may need to be updated when the Malagasy numbering plan changes.
Phone numbers generated by this package are intended for testing and seeding. They should not be used to contact real people.
CIN values
fakerMg()->cin(); // 123456789012
The generated value contains 12 digits without separators.
CIN generation is intended for testing only. The package does not verify whether a CIN was officially issued or belongs to a real person.
Laravel factories and seeders
The package can be used directly inside Laravel factories:
// database/factories/EmployeeFactory.php use Illuminate\Database\Eloquent\Factories\Factory; class EmployeeFactory extends Factory { public function definition(): array { return [ 'first_name' => fakerMg()->firstName(), 'last_name' => fakerMg()->lastName(), 'phone' => fakerMg()->phoneNumber(), 'cin' => fakerMg()->cin(), 'address' => (string) fakerMg()->address( region: 'Analamanga' ), ]; } }
Create 100 employees:
Employee::factory() ->count(100) ->create();
Important factory note
Generate values inside the factory definition so that every row receives fresh data.
Avoid calculating values once and reusing them:
// Avoid this pattern if you want fresh generated values. $employee = [ 'first_name' => fakerMg()->firstName(), 'last_name' => fakerMg()->lastName(), ]; Employee::factory() ->count(100) ->create($employee);
The factory definition or a loop in a seeder should call fakerMg() for each
record.
Seeder example
use Illuminate\Database\Seeder; class EmployeeSeeder extends Seeder { public function run(): void { for ($i = 0; $i < 100; $i++) { Employee::create([ 'first_name' => fakerMg()->firstName(), 'last_name' => fakerMg()->lastName(), 'address' => (string) fakerMg()->address( region: 'Analamanga' ), 'phone' => fakerMg()->phoneNumber(), 'cin' => fakerMg()->cin(), ]); } } }
Validation rules
The package provides Laravel validation rules for Malagasy phone numbers and CIN values.
use Manguithre\FakerMadagascar\Rules\MalagasyCin; use Manguithre\FakerMadagascar\Rules\MalagasyPhoneNumber; $request->validate([ 'telephone' => [ 'required', new MalagasyPhoneNumber(), ], 'cin' => [ 'required', new MalagasyCin(), ], ]);
MalagasyPhoneNumber
The phone validation rule accepts formats such as:
0321234567
032 12 345 67
+261321234567
+261 32 12 345 67
It validates the Malagasy mobile format and supported operator prefixes.
MalagasyCin
The CIN validation rule accepts a 12-digit Malagasy CIN format.
Separators are tolerated and stripped before validation:
123456789012
1234 5678 9012
1234-5678-9012
1234.5678.9012
The rule validates the format only. It does not verify whether the CIN belongs to a real person or was officially issued.
Artisan command
The package includes an Artisan command for previewing generated data.
Generate random addresses
php artisan fakermg:preview \
--count=10 \
--type=address
Generate random persons
php artisan fakermg:preview \
--count=5 \
--type=person
Generate contact data
php artisan fakermg:preview \
--type=contact
Export to JSON
php artisan fakermg:preview \
--count=10 \
--type=address \
--export=json
Export to CSV
php artisan fakermg:preview \
--count=10 \
--type=contact \
--export=csv
Export files are written to the system temporary directory. The command displays the generated file path after the export is completed.
Configuration
Publish the configuration file:
php artisan vendor:publish \
--tag=faker-madagascar-config
The configuration file is:
// config/faker-madagascar.php return [ /* |-------------------------------------------------------------------------- | Active regions |-------------------------------------------------------------------------- | | Restrict random address generation to specific regions. | An empty array enables all 23 regions. | */ 'active_regions' => [], ];
Restrict random generation to selected regions
'active_regions' => [ 'Analamanga', 'Atsinanana', ],
With this configuration, random address generation only uses the selected regions:
fakerMg()->address();
Forcing an inactive region throws an exception:
fakerMg()->address(region: 'Diana');
Region names in the configuration are case-insensitive:
'active_regions' => [ 'analamanga', 'ATSINANANA', ],
Using the package outside Laravel
The core service can also be used in a plain PHP application:
<?php require 'vendor/autoload.php'; $address = fakerMg()->address(); echo $address;
When Laravel is not available, the helper falls back to a standalone
FakerMadagascar instance.
You can also instantiate the service directly:
<?php require 'vendor/autoload.php'; use Manguithre\FakerMadagascar\FakerMadagascar; $faker = new FakerMadagascar(); echo $faker->fullName(); echo $faker->phoneNumber();
Testing the package in a fresh Laravel application
Create a fresh Laravel application:
composer create-project laravel/laravel demo-fakermg
cd demo-fakermg
If you are testing a local checkout of the package, configure the local Composer repository:
composer config repositories.fakermg path ../Faker-Madagascar
Install the local development version:
composer require manguithre/faker-madagascar:@dev
Then add a test route in routes/web.php:
use Illuminate\Support\Facades\Route; Route::get('/test', function () { return [ 'address' => (string) fakerMg()->address(), 'person' => fakerMg()->fullName(), 'phone' => fakerMg()->phoneNumber(), 'cin' => fakerMg()->cin(), ]; });
Start the development server:
php artisan serve
Open the displayed local URL and visit:
/test
Testing
Run the test suite with:
composer test
You can also run the package tests directly if the project provides a PHPUnit configuration:
vendor/bin/phpunit
Data sources
The package includes the following geographical data:
- 23 regions.
- 119 districts.
- 1,704 communes.
- 20,688 fokontany names.
The geographical dataset is sourced from julkwel/madagascar-map, released under the MIT License.
After updating the source geography files, rebuild the generated dataset with:
php build-geography.php
Phone prefixes are maintained using information from the ARTEC national numbering plan and other available Malagasy operator and numbering references.
Contributing
Contributions, corrections and improvements are welcome.
Before opening a pull request:
composer install
composer test
When contributing geographical data, please include the source and explain the reason for the change.
For new public methods, include:
- Tests.
- PHPDoc or README documentation.
- A usage example.
- Any relevant backward-compatibility considerations.
Versioning
This package follows semantic versioning whenever possible.
Breaking changes may require a major version update. Check the changelog and release notes before upgrading between major versions.
Credits
- Geographical data from julkwel/madagascar-map, released under the MIT License.
- Phone prefix references from ARTEC and Malagasy telecom resources.
- FakerPHP for the original Faker provider concept and ecosystem.
License
This package is open-sourced software licensed under the MIT License.
See the LICENSE file for more information.