voku / phonetic-algorithms
Phonetic-Algorithms for fuzzy searching | PHP
Requires
- php: >=7.0.0
- voku/portable-utf8: ~6.0
- voku/stop-words: ~2.0
Requires (Dev)
- phpunit/phpunit: ~6.0 || ~7.0 || ~9.0
This package is auto-updated.
Last update: 2026-08-21 15:57:09 UTC
README
Phonetic-Algorithms
Description
Fuzzy searching for words that sound alike but are written differently.
| Code | Class | Algorithm | Key |
|---|---|---|---|
de |
PhoneticGerman |
"Kölner Phonetik" (Wikipedia) | digits |
en |
PhoneticEnglish |
"metaphone" (Wikipedia), via the native PHP function | letters |
es |
PhoneticSpanish |
rule set documented in the class | letters |
fr |
PhoneticFrench |
"SOUNDEX FR" (roudoudou.com) | letters |
it |
PhoneticItalian |
rule set documented in the class | letters |
nl |
PhoneticDutch |
rule set documented in the class | letters |
pl |
PhoneticPolish |
rule set documented in the class | letters |
pt |
PhoneticPortuguese |
rule set documented in the class | letters |
"Kölner Phonetik", "metaphone" and "SOUNDEX FR" are published algorithms and are implemented as published.
The other languages have no single published standard, so they are rule sets that are documented in the class itself: every class carries its complete sound table in the docblock, and every row of that table is pinned by a test. They are built for the mistakes people really make in that language, for example:
(new Phonetic('es'))->phonetic_word('vaca'); // 'BAKA' (new Phonetic('es'))->phonetic_word('baca'); // 'BAKA' - "b" and "v" are one sound (new Phonetic('nl'))->phonetic_word('Meijer'); // 'MYER' (new Phonetic('nl'))->phonetic_word('Meyer'); // 'MYER' - "ij", "ei" and "y" are one sound (new Phonetic('pl'))->phonetic_word('Wałęsa'); // 'VALESA' (new Phonetic('pl'))->phonetic_word('Walesa'); // 'VALESA' - a query without diacritics still matches
Codes from different languages are not comparable with each other: pick the language of the data you are searching in.
Installation
- Install and use composer in your project.
- Require this package via composer:
composer require voku/phonetic-algorithms
Usage
You the "phonetic_word"-method if you need a fuzzy-search for single words e.g. last-names or product-names.
use voku\helper\Phonetic; $words = array( 'Moelleken', 'Mölleken', 'Möleken', 'Moeleken', 'Moellecken', 'Möllecken', 'Mölecken', ); $phonetic = new Phonetic('de'); foreach ($words as $word) { $phonetic->phonetic_word($string); // '6546' }
You can use the "phonetic_sentence"-method to process sentences.
use voku\helper\Phonetic; $string = 'Ein Satz mit vielen Wortern'; $phonetic = new Phonetic('de'); $phonetic->phonetic_sentence($string, (bool) false, (false|int) false); // [ // 'Ein' => '06', // 'Satz' => '8', // 'mit' => '62', // 'vielen' => '356', // 'Wortern' => '37276' // ]
You can use the "phonetic_matches"-method to search for words in an array of words.
use voku\helper\Phonetic; $phonetic = new Phonetic('de'); $tests = array( 'Moelleken', // '6546', 'Mölleken', // '6546', 'Möleken', // '6546', 'Moeleken', // '6546', 'oder', // '027', 'was', // '38', 'Moellecken', // '6546', 'Möllecken', // '6546', 'Mölecken', // '6546', ); $phonetic->phonetic_matches('Moelleken', $tests); // [ // 'Moelleken' => 'Moelleken', // 'Mölleken' => 'Moelleken', // 'Möleken' => 'Moelleken', // 'Moeleken' => 'Moelleken', // 'Moellecken' => 'Moelleken', // 'Möllecken' => 'Moelleken', // 'Mölecken' => 'Moelleken', // ]
Development
Coding-agent work in this repository runs through
voku/agent-loop: plan, approve,
implement, validate with recorded evidence, review, close. The board, the task
contracts and the run receipts live under .agent-loop/.
make agent_loop_install bin/agent-loop init status bin/agent-loop board summary
See docs/agent-loop.md for the setup and docs/agent-loop-dogfood.md for what the workflow did and did not catch while these languages were added.
History
See CHANGELOG for the full history of changes.