PHPackages                             zendevio/bmpm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. zendevio/bmpm

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

zendevio/bmpm
=============

Modern PHP 8.4+ implementation of the Beider-Morse Phonetic Matching (BMPM) algorithm for multilingual name matching

v1.0.1(5mo ago)27GPL-3.0-or-laterPHPPHP ^8.4CI failing

Since Dec 13Pushed 5mo agoCompare

[ Source](https://github.com/zendevio/bmpm-php)[ Packagist](https://packagist.org/packages/zendevio/bmpm)[ Docs](https://github.com/zendevio/bmpm-php)[ RSS](/packages/zendevio-bmpm/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (3)Used By (0)

BMPM - Beider-Morse Phonetic Matching for PHP
=============================================

[](#bmpm---beider-morse-phonetic-matching-for-php)

[![PHP Version](https://camo.githubusercontent.com/02463ad42fbbb8e930dc93f83e8b2ecd9ad3f718d33bb429f5f8f792f9cfd2e5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e342d626c75652e737667)](https://www.php.net/)[![License](https://camo.githubusercontent.com/cf49d2a25028535e33d3741bc3faf766b098fe3b856d711f94da8057b9cee0df/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d47504c2d2d332e302d677265656e2e737667)](LICENSE)![Tests](https://camo.githubusercontent.com/a4da54b7bbdc18942accdd3723933d625fba49ffeab6d3b3c52b68fd33d3590b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d34303025323070617373696e672d627269676874677265656e2e737667)![Coverage](https://camo.githubusercontent.com/30e9d2f098fd8f1d3fb92897709d0fe6ce6ceb11f7e5c01feffd88fa5c15ef72/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d39372e35312532352d627269676874677265656e2e737667)![MSI](https://camo.githubusercontent.com/f6e4de9430828460e7a188b439d49152d8b5697c60d870fa9e5169b0e3fb1677/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d53492d38312532352d627269676874677265656e2e737667)![PHPStan](https://camo.githubusercontent.com/b6d441ad4fe8332cb16c72aa27f22cc685181dfd74ae34964afc92c6c1146b3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e2e737667)

A modern PHP 8.4+ implementation of the **Beider-Morse Phonetic Matching (BMPM)** algorithm for multilingual name matching. This library enables phonetic comparison of names across 20+ languages, making it ideal for genealogical research, record linkage, and fuzzy name searching.

Features
--------

[](#features)

- **Multilingual Support**: 20 languages including Arabic, Cyrillic, Greek, Hebrew, and Latin-based scripts
- **Three Name Type Modes**: Generic, Ashkenazic, and Sephardic variants
- **Dual Matching Accuracy**: Exact and Approximate modes for precision vs. recall trade-offs
- **Daitch-Mokotoff Soundex**: Included D-M Soundex implementation for Slavic/Yiddish names
- **Modern PHP**: Built for PHP 8.4+ with enums, readonly classes, and strict typing
- **Immutable API**: Fluent, immutable builder pattern for safe configuration
- **Well Tested**: 400+ tests with 97.51% coverage, 81% MSI (mutation score), PHPStan level max

Installation
------------

[](#installation)

```
composer require zendevio/bmpm
```

### Requirements

[](#requirements)

- PHP 8.4 or higher
- `ext-mbstring` - Multibyte string support
- `ext-intl` - Internationalization support
- `ext-json` - JSON support

Quick Start
-----------

[](#quick-start)

```
use Zendevio\BMPM\BeiderMorse;

// Simple usage
$encoder = new BeiderMorse();
$phonetic = $encoder->encode('Schwarzenegger');
// Returns: "(Svarcenegr|## more alternatives...)"

// Check if two names might match
$matches = $encoder->matches('Smith', 'Schmidt');
// Returns: true (they share phonetic codes)

// Get similarity score
$similarity = $encoder->similarity('Mueller', 'Miller');
// Returns: float between 0.0 and 1.0
```

Configuration
-------------

[](#configuration)

```
use Zendevio\BMPM\BeiderMorse;
use Zendevio\BMPM\Enums\NameType;
use Zendevio\BMPM\Enums\MatchAccuracy;
use Zendevio\BMPM\Enums\Language;

// Fluent configuration
$encoder = BeiderMorse::create()
    ->withNameType(NameType::Ashkenazic)      // Generic, Ashkenazic, or Sephardic
    ->withAccuracy(MatchAccuracy::Approximate) // Exact or Approximate
    ->withLanguages(Language::German, Language::Polish);

// Encode to array of alternatives
$alternatives = $encoder->encodeToArray('Kowalski');
// Returns: ['kovalski', 'kovalske', ...]

// Batch encoding
$results = $encoder->encodeBatch(['Smith', 'Jones', 'Williams']);
// Returns: ['Smith' => '(smit|...)', 'Jones' => '...', ...]
```

Name Types
----------

[](#name-types)

TypeDescriptionLanguages**Generic**General-purpose matching20 languages**Ashkenazic**Eastern European Jewish names11 languages**Sephardic**Mediterranean Jewish names6 languages```
// Ashkenazic mode for Eastern European Jewish names
$encoder = BeiderMorse::create()
    ->withNameType(NameType::Ashkenazic);

// Sephardic mode for Spanish/Portuguese Jewish names
$encoder = BeiderMorse::create()
    ->withNameType(NameType::Sephardic);
```

Language Detection
------------------

[](#language-detection)

The library automatically detects the likely language(s) of a name:

```
$encoder = new BeiderMorse();

// Detect all possible languages
$languages = $encoder->detectLanguages('Müller');
// Returns: [Language::German]

// Get primary language
$primary = $encoder->detectPrimaryLanguage('Kowalski');
// Returns: Language::Polish
```

Daitch-Mokotoff Soundex
-----------------------

[](#daitch-mokotoff-soundex)

For Slavic and Yiddish surname matching:

```
$encoder = new BeiderMorse();

$soundex = $encoder->soundex('Schwarzenegger');
// Returns: "479465 474659" (multiple codes for ambiguous spellings)

$soundex = $encoder->soundex('Cohen');
// Returns: "560000 460000"
```

Advanced Usage
--------------

[](#advanced-usage)

### Restrict to Specific Languages

[](#restrict-to-specific-languages)

```
$encoder = BeiderMorse::create()
    ->withLanguages(Language::German, Language::English, Language::French);

// Or using a bitmask directly
$encoder = BeiderMorse::create()
    ->withLanguageMask(Language::German->value | Language::English->value);
```

### Custom Data Path

[](#custom-data-path)

```
// Use custom rule files location
$encoder = BeiderMorse::create()
    ->withDataPath('/path/to/custom/rules');
```

### Direct Engine Access

[](#direct-engine-access)

For advanced use cases, access the engine directly:

```
use Zendevio\BMPM\Engine\PhoneticEngine;
use Zendevio\BMPM\Engine\LanguageDetector;
use Zendevio\BMPM\Rules\RuleLoader;

$ruleLoader = RuleLoader::create();
$detector = new LanguageDetector($ruleLoader);
$engine = new PhoneticEngine($ruleLoader, $detector);

$result = $engine->encode('name', NameType::Generic, MatchAccuracy::Approximate);
```

API Reference
-------------

[](#api-reference)

### BeiderMorse (Main Facade)

[](#beidermorse-main-facade)

MethodDescription`encode(string $name): string`Encode name to phonetic representation`encodeToArray(string $name): array`Get all phonetic alternatives as array`encodeBatch(array $names): array`Encode multiple names at once`matches(string $a, string $b): bool`Check if two names match phonetically`similarity(string $a, string $b): float`Get similarity score (0.0 - 1.0)`detectLanguages(string $name): array`Detect possible languages`detectPrimaryLanguage(string $name): Language`Get most likely language`soundex(string $name): string`Get D-M Soundex encoding### Configuration Methods

[](#configuration-methods)

MethodDescription`withNameType(NameType $type): self`Set name type variant`withAccuracy(MatchAccuracy $accuracy): self`Set matching accuracy`withLanguages(Language ...$langs): self`Restrict to specific languages`withLanguageMask(int $mask): self`Set language bitmask directly`withAutoLanguageDetection(): self`Enable automatic detection`withDataPath(string $path): self`Set custom rules pathSupported Languages
-------------------

[](#supported-languages)

### Generic Mode (20 languages)

[](#generic-mode-20-languages)

Arabic, Cyrillic, Czech, Dutch, English, French, German, Greek, Greek (Latin), Hebrew, Hungarian, Italian, Latvian, Polish, Portuguese, Romanian, Russian, Spanish, Turkish

### Ashkenazic Mode (11 languages)

[](#ashkenazic-mode-11-languages)

Cyrillic, English, French, German, Hebrew, Hungarian, Polish, Romanian, Russian, Spanish

### Sephardic Mode (6 languages)

[](#sephardic-mode-6-languages)

French, Hebrew, Italian, Portuguese, Spanish

How It Works
------------

[](#how-it-works)

The Beider-Morse algorithm:

1. **Language Detection**: Analyzes spelling patterns to identify likely source language(s)
2. **Phonetic Rules**: Applies language-specific transformation rules
3. **Approximation**: Generates phonetic codes that capture pronunciation variants
4. **Multi-output**: Produces multiple codes for ambiguous spellings

This enables matching names like:

- "Smith" ↔ "Schmidt" ↔ "Schmitt"
- "Cohen" ↔ "Kohn" ↔ "Cohn" ↔ "Cahan"
- "Schwarzenegger" ↔ "Shvarceneger"

Documentation
-------------

[](#documentation)

- [Getting Started](docs/getting-started.md)
- [API Reference](docs/api-reference.md)
- [Advanced Usage](docs/advanced-usage.md)
- [Contributing](CONTRIBUTING.md)
- [Changelog](CHANGELOG.md)

Testing &amp; Quality
---------------------

[](#testing--quality)

```
# Run tests
composer test

# Run with coverage
composer test:coverage

# Static analysis (PHPStan level max)
composer analyse

# Code style check
composer cs-check

# Code style fix
composer cs-fix

# Mutation testing (min 80% MSI required)
composer infection

# Automated refactoring
composer rector:dry    # Preview changes
composer rector        # Apply changes

# Run all checks
composer check         # cs-check, analyse, test

# Full CI pipeline
composer ci            # security, cs-check, analyse, test, infection
```

Credits
-------

[](#credits)

- **Alexander Beider** - Original BMPM algorithm
- **Stephen P. Morse** - Original BMPM algorithm and [website](https://stevemorse.org/phoneticinfo.htm)
- **Alin M. Gheorghe** - PHP 8.4+ implementation

License
-------

[](#license)

This library is licensed under the [GPL-3.0 License](LICENSE), the same license as the original BMPM implementation.

Related Resources
-----------------

[](#related-resources)

- [BMPM Official Website](https://stevemorse.org/phoneticinfo.htm)
- [One-Step Phonetic Search Tool](https://stevemorse.org/phonetics/bmpm.htm)
- [Algorithm Description (PDF)](https://stevemorse.org/phonetics/bmpm.pdf)

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance72

Regular maintenance activity

Popularity9

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

155d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/341365a979c82ba6b82f14f6d607557d04996d9de130a9cd1648ce4684314850?d=identicon)[zendevio](/maintainers/zendevio)

---

Tags

transliterationmatchingnamesphoneticsoundexlinguisticsbeider-morsegenealogybmpm

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/zendevio-bmpm/health.svg)

```
[![Health](https://phpackages.com/badges/zendevio-bmpm/health.svg)](https://phpackages.com/packages/zendevio-bmpm)
```

###  Alternatives

[jbroadway/urlify

A fast PHP slug generator and transliteration library that converts non-ascii characters for use in URLs.

6737.4M62](/packages/jbroadway-urlify)[ausi/slug-generator

Slug Generator

8002.2M22](/packages/ausi-slug-generator)[voku/urlify

PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.

254.1M7](/packages/voku-urlify)[fresh/transliteration

PHP library for transliteration.

52135.6k1](/packages/fresh-transliteration)[ashtokalo/php-translit

PHP library to convert text from one script to another.

40146.2k1](/packages/ashtokalo-php-translit)[heureka/inflection

Czech inflection library

6163.9k](/packages/heureka-inflection)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
