PHPackages                             mlocati/idna - 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. [Localization &amp; i18n](/categories/localization)
4. /
5. mlocati/idna

ActiveLibrary[Localization &amp; i18n](/categories/localization)

mlocati/idna
============

Library for International Domain Names (IDNA) 2008

1.1.3(1y ago)9877.7k—3.9%32MITPHPPHP &gt;=7.1

Since Nov 24Pushed 1y ago1 watchersCompare

[ Source](https://github.com/mlocati/idna)[ Packagist](https://packagist.org/packages/mlocati/idna)[ Docs](https://github.com/mlocati/idna)[ Fund](https://paypal.me/mlocati)[ GitHub Sponsors](https://github.com/mlocati)[ RSS](/packages/mlocati-idna/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (7)Dependencies (1)Versions (8)Used By (2)

[![Tests](https://github.com/mlocati/idna/actions/workflows/tests.yml/badge.svg)](https://github.com/mlocati/idna/actions/workflows/tests.yml)

International Domain Names PHP library
======================================

[](#international-domain-names-php-library)

Introduction &amp; terminology
------------------------------

[](#introduction--terminology)

Historically, we've been able to use domain names composed only by [ASCII characters](https://en.wikipedia.org/wiki/ASCII) (for instance: `www.example.com`).

A new technique, called **Internationalized Domain Names** (***IDN*** for short), allows you to use most of the [Unicode characters](https://en.wikipedia.org/wiki/Universal_Character_Set_characters), so that you can have for instance `www.例.中国`.

To grant compatibility with all the existing software that makes internet work, domain names containing non-ASCII characters are represented in **Punycode**, a special format that uses ASCII-only characters.

Mapping
-------

[](#mapping)

The generation of Punycode starting from an IDN should be **case insensitive**: browsing to `www.example.com` should be the same as browsing to `www.Example.COM`.

In PHP, converting strings to lower case is as easy as calling `strtolower`, but this function does not work with characters outside the ASCII characters (in fact, it may mess up the IDN names). If you have the `mbstring` PHP extension, you may think to use the `mb_strtolower` PHP function it offers.

By the way, even `mb_strtolower` isn't a good choice, for these reasons:

1. the `mbstring` PHP extension may not be available
2. the `mb_strtolower` behaviour changes across different PHP versions (for instance, `Ԩ` is correctly converted to `ԩ` for PHP 7.0, but prior versions kept `Ԩ`)
3. `mb_strtolower` does not translate a lot of Unicode characters that are suggested by the standards

Unicode offers a [mapping table](https://www.unicode.org/Public/idna/latest/IdnaMappingTable.txt) with the recommended mapping (for instance, case normalization like `A` to `a`, but also `。` to `.`).

Deviation
---------

[](#deviation)

There are two standards that define the mapping that should be applied to IDN, IDNA2003 and IDNA2008. IDNA2008 is backward compatible with IDNA2003, but there are some incompatible differences.

For instance, IDNA2003 required that `ß` mapped to `ss`, whereas IDNA2008 allows the usage of `ß`. So, older browsers and client softwares resolved `www.schloß.com` to the Punycode corresponding to `www.schloss.com`, whereas newer browsers resolve it to the Punycode of `www.schloß.com`.

Since the resulting Punycode is different (it's called ***deviation***), this lead to big security issues, and you *need* to know that a domain name is deviated.

Advantages of this library
--------------------------

[](#advantages-of-this-library)

- no dependencies from any PHP extension
- not dependent from any other PHP library
- consistency across different PHP versions
- results are granted to follow the standards (it's not just a bare *multibyte to punycode* conversion library)
- designed with speed in mind
- compatible with any PHP version ranging from PHP 5.3 to the most recent PHP versions (8.2 at the time of writing this)

Sample usage
------------

[](#sample-usage)

```
require_once 'autoload.php'; // Not required if you use composer

$domain = \MLocati\IDNA\DomainName::fromName('www。schloß.COM');

echo "Name: ", $domain->getName(), "\n";
echo "Punycode: ", $domain->getPunycode(), "\n";
echo "Deviated: ", $domain->isDeviated() ? 'yes' : 'no', "\n";
echo "Deviated Name: ", $domain->getDeviatedName(), "\n";
echo "Deviated Punycode: ", $domain->getDeviatedPunycode(), "\n";
```

output:

```
Name: www.schloß.com
Punycode: www.xn--schlo-pqa.com
Deviated: yes
Deviated Name: www.schloss.com
Deviated Punycode: www.schloss.com

```

Do you really want to say thank you?
------------------------------------

[](#do-you-really-want-to-say-thank-you)

You can offer me a [monthly coffee](https://github.com/sponsors/mlocati) or a [one-time coffee](https://paypal.me/mlocati) 😉

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity45

Moderate usage in the ecosystem

Community17

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 95% of commits — single point of failure

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 ~489 days

Recently: every ~165 days

Total

7

Last Release

525d ago

PHP version history (2 changes)1.0.0PHP &gt;=5.3

1.1.3PHP &gt;=7.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/6e9d7ece045fc89575e083ee4852edf31218df403c84f41a0de01863dae982f5?d=identicon)[mlocati](/maintainers/mlocati)

---

Top Contributors

[![mlocati](https://avatars.githubusercontent.com/u/928116?v=4)](https://github.com/mlocati "mlocati (57 commits)")[![cgoedel](https://avatars.githubusercontent.com/u/116256446?v=4)](https://github.com/cgoedel "cgoedel (1 commits)")[![FlyingDR](https://avatars.githubusercontent.com/u/822673?v=4)](https://github.com/FlyingDR "FlyingDR (1 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (1 commits)")

---

Tags

internationalizationi18nunicodel10nidnaidnpunycodeasciiinternationaldomainansinamedomain namedomainsnamesidna2008idna2003internationalizeddomain namesinternational domaininternational domainsinternational nameinternational namesinternational domain nameinternational domain namesinternationalized domaininternationalized domainsinternationalized nameinternationalized namesinternationalized domain nameinternationalized domain names

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mlocati-idna/health.svg)

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

###  Alternatives

[symfony/intl

Provides access to the localization data of the ICU library

2.6k199.8M1.1k](/packages/symfony-intl)[gettext/languages

gettext languages with plural rules

7530.3M11](/packages/gettext-languages)[punic/punic

PHP-Unicode CLDR

1542.9M29](/packages/punic-punic)[aplus/language

Aplus Framework Language Library

2351.7M15](/packages/aplus-language)[aura/intl

The Aura Intl package provides internationalization tools, specifically message translation.

898.3M4](/packages/aura-intl)[inpsyde/multilingual-press

Simply THE multisite-based free open source plugin for your multilingual websites.

2414.0k1](/packages/inpsyde-multilingual-press)

PHPackages © 2026

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