PHPackages                             boronczyk/localization-middleware - 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. boronczyk/localization-middleware

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

boronczyk/localization-middleware
=================================

PSR-15 middleware to assist primarily with language-based content negotiation and various other localization tasks.

2.0.2(1y ago)2667.5k↑228.6%9MITPHPPHP &gt;=7.2CI failing

Since Jun 2Pushed 1y ago3 watchersCompare

[ Source](https://github.com/tboronczyk/localization-middleware)[ Packagist](https://packagist.org/packages/boronczyk/localization-middleware)[ Docs](https://github.com/tboronczyk/localization-middleware)[ RSS](/packages/boronczyk-localization-middleware/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (7)Dependencies (4)Versions (11)Used By (0)

Localization Middleware
=======================

[](#localization-middleware)

[![tboronczyk](https://camo.githubusercontent.com/6a7ff2b838b0ad68e2068b35034d3d48edb7196ade0d996c0e1589dc59d6b4d5/68747470733a2f2f636972636c6563692e636f6d2f67682f74626f726f6e637a796b2f6c6f63616c697a6174696f6e2d6d6964646c65776172652e7376673f7374796c653d736869656c64)](https://circleci.com/gh/tboronczyk/localization-middleware)[![codecov](https://camo.githubusercontent.com/3dadef980f1cf8d9a148f766e0cf8fc4c60ff9776e999bc9999ae21f687cbee1/68747470733a2f2f636f6465636f762e696f2f67682f74626f726f6e637a796b2f6c6f63616c697a6174696f6e2d6d6964646c65776172652f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/tboronczyk/localization-middleware)[![FOSSA Status](https://camo.githubusercontent.com/a2fe4e4235e46fd96f5d2080e6246baa76ca2cd5bee2d72c785ddc2b574067b9/68747470733a2f2f6170702e666f7373612e696f2f6170692f70726f6a656374732f67697425324268747470732533412532462532466769746875622e636f6d25324674626f726f6e637a796b2532466c6f63616c697a6174696f6e2d6d6964646c65776172652e7376673f747970653d736869656c64)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Ftboronczyk%2Flocalization-middleware?ref=badge_shield)

Middleware to assist primarily with language-based content negotiation and various other localization tasks. It determines the appropriate locale based on the client’s request and sets an attribute on the request object making the value available to the rest of your application. Its callback hook offers a convenient way to initialize other libraries or execute code based on the locale value.

**Version 2 conforms to [PSR-15](https://www.php-fig.org/psr/psr-15/). Use version ^1.4 if you require the so-called “Double Pass” approach using `__invoke()`.**

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

[](#installation)

Localization Middleware is installable via [Composer](https://getcomposer.org).

```
composer require boronczyk/localization-middleware

```

Basic Example
-------------

[](#basic-example)

Here is a basic usage example:

```
use Boronczyk\LocalizationMiddleware;

// register the middleware with your PSR-15 compliant framework
$availableLocales = ['en_US', 'fr_CA', 'es_MX', 'eo'];
$defaultLocale = 'en_US';
$app->add(new LocalizationMiddleware($availableLocales, $defaultLocale));

// reference the locale in your route callback
$app->get('/', function ($req, $resp, $args) {
    $attrs = $req->getAttributes();
    $locale = $attrs['locale'];
    return $resp->write("The locale is $locale.");
});

```

More Advanced Example
---------------------

[](#more-advanced-example)

Here is a more advanced usage example:

```
use Boronczyk\LocalizationMiddleware;

// instanciate the middleware
$availableLocales = ['en_US', 'fr_CA', 'es_MX', 'eo'];
$defaultLocale = 'en_US';
$middleware = new LocalizationMiddleware($availableLocales, $defaultLocale);

// specify the order in which inputs are searched for the locale
$middleware->setSearchOrder([
    LocalizationMiddleware::FROM_CALLBACK,
    LocalizationMiddleware::FROM_URI_PATH,
    LocalizationMiddleware::FROM_URI_PARAM,
    LocalizationMiddleware::FROM_COOKIE,
    LocalizationMiddleware::FROM_HEADER
]);

// attempt to identify the locale using a callback
$middleware->setSearchCallback(
    function (Request $req) use (Container $c): string {
        $db = $c->get('GeoIp2Database');
        switch ($db->country($req->getAttribute('ip_address')) {
            case 'CA':
                return 'fr_CA';
            case 'US':
                return 'en_US';
            case 'MX':
                return 'es_MX';
            default:
                return '';
        }
    }
);

// execute logic once the locale has been identified
$middleware->setLocaleCallback(function (string $locale) {
    putenv("LANG=$locale");
    setlocale(LC_ALL, $locale);
    bindtextdomain('messages', 'Locale');
    bind_textdomain_codeset('messages', 'UTF-8');
    textdomain('messages');
});

// change the name of the uri parameter identifying the locale
$middleware->setUriParamName('hl');

// register the middleware with your PSR-15 compliant framework
$app->add($middleware);

// reference the locale in your route callback
 $app->get('/', function ($req, $resp, $args) {
    $attrs = $req->getAttributes();
    $locale = $attrs['locale'];
    $text = sprintf(_('The locale is %s.'), $locale);
    return $resp->write($text);
});

```

Configurable Behavior
---------------------

[](#configurable-behavior)

The middleware component’s behavior is configurable though the following methods:

- `setAvailableLocales(array $locales)`
    Sets the list of available locales after an instance has already been created.

    ```
    $middleware->setAvailableLocales(['en_US', 'fr_CA', 'pt_BR']);

    ```
- `setDefaultLocale(string $locale)`
    Sets the default locale to return after an instance has already been created.

    ```
    $middleware->setDefaultLocale('fr_CA');

    ```
- `setSearchOrder(array $order)`
    Sets the order in which inputs are searched for a suitable locale.

    ```
    $middleware->setSearchOrder([
        LocalizationMiddleware::FROM_URI_PATH,
        LocalizationMiddleware::FROM_URI_PARAM,
        LocalizationMiddleware::FROM_COOKIE,
        LocalizationMiddleware::FROM_HEADER
    ]);

    ```

    Adding or removing locale sources from the order modifies the search domain.

    ```
    // only search cookies and the Accept-Language header
    $middleware->setSearchOrder([
        LocalizationMiddleware::FROM_COOKIE,
        LocalizationMiddleware::FROM_HEADER
    ]);

    ```

    The available locale source constants are:

    - `LocalizationMiddleware::FROM_URI_PATH`
        Search for the locale in the URI path. The first directory value in the request path is considered the locale, for example `https://example.com/en_US/foo`.
    - `LocalizationMiddleware::FROM_URI_PARAM`
        Search for the locale in the URI parameter (the default parameter name is `locale`).
    - `LocalizationMiddleware::FROM_COOKIE`
        Search for the locale in cookies (the default cookie name is `locale`). *Note: Using this will set a locale cookie for subsequent requests.*
    - `LocalizationMiddleware::FROM_HEADER`
        Search for the locale in the HTTP `Accept-Language` header. Header searches make a best-effort search for locales, languages, and possible quality modifiers.
    - `LocalizationMiddleware::FROM_CALLBACK`
        Search for the locale using a custom callback function. The callback function is set with `setSearchCallback()`.

    The default order is: `FROM_URI_PATH`, `FROM_URI_PARAM`, `FROM_COOKIE`, `FROM_HEADER`. *Note that `FROM_CALLBACK` is **not** included by default.*
- `setSearchCallback(callable $func)`
    Sets a callback that is invoked when searching for the locale, offering the developer a chance to inject a locale of their choosing into the search. The callable’s signature is: `function (Request $req): string`.

    ```
    $middleware->setSearchCallback(
        function (Request $req) use (Container $c): string {
            $db = $c->get('GeoIp2Database');
            switch ($db->country($req->getAttribute('ip_address')) {
                case 'CA':
                    return 'fr_CA';
                case 'US':
                    return 'en_US';
                case 'MX':
                    return 'es_MX';
                default:
                    return '';
            }
        }
    );

    ```
- `setReqAttrName(string $name)`
    Sets the name for the attribute attached to the request. The default name is `locale`.

    ```
    $middleware->setReqAttrName('lang');

    $app->get('/', function ($req, $resp, $args) {
        $attrs = $req->getAttributes();
        $lang = $attrs['lang'];
    });

    ```
- `setUriParamName(string $name)`
    Sets the name for a URI parameter to specify the locale. The default name is `locale`.

    ```
    $middleware->setUriParamName('lang');

    https://example.com/mypage?lang=es_MX

    ```
- `setCookieName(string $name)`
    Sets the name of the cookie to store the determined locale. The default name is `locale`.

    ```
    $middleware->setCookieName('lang');

    ```
- `setCookiePath(string $path)`
    Sets the path of the cookie for which it will be returned by the client. The default path is `/`.

    ```
    $middleware->setCookiePath("/dir");

    ```
- `setCookieExpire(int $secs)`
    Sets the duration of the locale cookie. The default value is 30 days.

    ```
    $middleware->setCookieExpire(3600); // 1 hour

    ```
- `setLocaleCallback(callable $func)`
    Sets a callback that is invoked after the middleware identifies the locale, offering the developer a chance to conveniently initialize other libraries or execute other code with the value. The callable’s signature is: `function (string $locale)`.

    ```
    $middleware->setLocaleCallback(function (string $locale) {
        putenv("LANG=$locale");
        setlocale(LC_ALL, $locale);
        bindtextdomain('messages', 'Locale');
        bind_textdomain_codeset('messages', 'UTF-8');
        textdomain('messages');
    });

    ```

License
-------

[](#license)

[![FOSSA Status](https://camo.githubusercontent.com/0bebfde2b82fe759ab117172d8b9e173f401726c453e3dd76721778e414bdc7e/68747470733a2f2f6170702e666f7373612e696f2f6170692f70726f6a656374732f67697425324268747470732533412532462532466769746875622e636f6d25324674626f726f6e637a796b2532466c6f63616c697a6174696f6e2d6d6964646c65776172652e7376673f747970653d6c61726765)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Ftboronczyk%2Flocalization-middleware?ref=badge_large)

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity41

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 84.9% 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 ~310 days

Recently: every ~595 days

Total

10

Last Release

527d ago

Major Versions

1.4.1 → 2.02020-04-26

PHP version history (4 changes)1.0PHP ^7.0

2.0PHP ^7.2

2.0.1PHP ^7.2 || ^8.0

2.0.2PHP &gt;=7.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/696497?v=4)[Timothy Boronczyk](/maintainers/tboronczyk)[@tboronczyk](https://github.com/tboronczyk)

---

Top Contributors

[![tboronczyk](https://avatars.githubusercontent.com/u/696497?v=4)](https://github.com/tboronczyk "tboronczyk (62 commits)")[![fgagne](https://avatars.githubusercontent.com/u/13245424?v=4)](https://github.com/fgagne "fgagne (8 commits)")[![bakurin](https://avatars.githubusercontent.com/u/3139385?v=4)](https://github.com/bakurin "bakurin (2 commits)")[![fossabot](https://avatars.githubusercontent.com/u/29791463?v=4)](https://github.com/fossabot "fossabot (1 commits)")

---

Tags

content-negotiationlanguagemiddlewarepsr-15slim-frameworklocalizationslimpsr-15

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/boronczyk-localization-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/boronczyk-localization-middleware/health.svg)](https://phpackages.com/packages/boronczyk-localization-middleware)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.3k543.5M2.6k](/packages/aws-aws-sdk-php)[cakephp/cakephp

The CakePHP framework

8.9k19.5M1.8k](/packages/cakephp-cakephp)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k656.1k38](/packages/neuron-core-neuron-ai)[mezzio/mezzio

PSR-15 Middleware Microframework

3923.8M126](/packages/mezzio-mezzio)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35789.4k2](/packages/telnyx-telnyx-php)

PHPackages © 2026

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