PHPackages                             drunomics/multisite-request-matcher - 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. drunomics/multisite-request-matcher

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

drunomics/multisite-request-matcher
===================================

Matches requests to multisite hosts.

1.7.2(3y ago)735.7k3[1 issues](https://github.com/drunomics/multisite-request-matcher/issues)[4 PRs](https://github.com/drunomics/multisite-request-matcher/pulls)MITPHPCI failing

Since Mar 18Pushed 3mo agoCompare

[ Source](https://github.com/drunomics/multisite-request-matcher)[ Packagist](https://packagist.org/packages/drunomics/multisite-request-matcher)[ RSS](/packages/drunomics-multisite-request-matcher/feed)WikiDiscussions 1.x Synced 4w ago

READMEChangelog (10)Dependencies (2)Versions (27)Used By (0)

Multisite Request Matcher
=========================

[](#multisite-request-matcher)

Matches requests to multisites based upon configuration driven by environment variables. The packages works well with symfony/dotenv and symfony/http-foundation as used by drupal/core.

The multisite setup supports configuration via a common base-domain ($APP\_MULTISITE\_DOMAIN) or via per site domains. Via environment-dependent variables the common base-domain may be enabled for preview environments only also. The configured default site is used when the common multisite base-domain is accessed without any suiting prefix. Next, it's used for CLI invocations if no SITE variable is given a.

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

[](#installation)

```
composer require drunomics/multisite-request-matcher

```

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

[](#configuration)

The package support construction site URLs via via a common base-domain ($APP\_MULTISITE\_DOMAIN) or via per site domains. Optional, site variants like "admin" or "api" are supported - useful if the app uses multiple hosts for things like the admin interface or an API endpoint.

That can be used to construct URLs like the following:

- Commom multisite domain:

    ```
      https://site-a_stage.example.com
      https://site-b_stage.example.com

    ```
- Per site domains:

    ```
      https://www.site-a.com
      https://wwww.site-b.com

    ```
- Common multisite domain with variants:

    ```
      https://api--site-a_stage.example.com
      https://api--site-b_stage.example.com
      https://admin--site-a_stage.example.com
      https://admin--site-b_stage.example.com

    ```
- Per site domains with variants:

    ```
      https://api.site-a.com
      https://api.site-b.com
      https://admin.site-a.com
      https://admin.site-b.com

    ```

The following environment variables may be set to configure the request matcher:

Variable nameRequiredExample ValueDescriptionTRUSTED\_PROXIESNo127.0.0.1A list of IP addresses or subnets, separated by space.HEADER\_FORWARDED\_HOSTNoX\_FORWARDED\_HOSTA non-standard value for the host header.APP\_SITESYessite-a site-bThe list of site names, separated by space. May contain lowercase characters and dashes only.APP\_DEFAULT\_SITENosite-aThe default site to set. If not set, the first set will be set by default.APP\_SITE\_VARIANTSNoadmin apiAn optional list of variants; i.e. variants of the same site.APP\_SITE\_VARIANT\_SEPARATORNo--The separator between the variant name and the host, defaults to "--".APP\_MULTISITE\_DOMAIN~stage.codebase.devA common base domain for all sites. Required when multisite base domains should be used.APP\_MULTISITE\_DOMAIN\_PREFIX\_SEPARATORNo\_The separator between the site name and the common multisite base domain. Defaults to '\_'.APP\_SITE\_DOMAIN\_\_{{ SITE }}~site-a.comThe per-site domain - required when per-site domains should be used. One variable per site must be provided with dashes replaced to underscores, e.g. for site-a the variable name would be `APP_SITE_DOMAIN__site_a`APP\_SITE\_DOMAIN\_ALIASES\_\_{{ SITE }}Nosite-a.hoster.com,site-a.hoster.comComma separated, per-site domain aliases that are allowed in addition to the main domain. Useful when access should be allowed via some non-primary domains also; e.g., when behind a CDN. One variable per site must be provided with dashes replaced to underscores, e.g. for site-a the variable name would be `APP_SITE_DOMAIN_ALIASES__site_a`APP\_SITE\_DOMAIN~site-a.comIf an environment is bound to a fixed site, the site's domain. Requires SITE to be predefined.APP\_SITE\_DOMAIN\_ALIASESNosite-a.host.com,site-a.host2.comIf an environment is bound to a fixed site, the site's domain aliases (see above). Requires SITE to be predefined.Results
-------

[](#results)

- The matched host is set as trusted host to the symfony/http-foundation request API via trusted host patterns.
- The following environment variables are set:

Variable nameExample ValueDescriptionSITEsite-aThe active site.SITE\_VARIANTapiThe active site variant. Empty if no variant is active.SITE\_HOSTapi--site-b\_stage.example.comThe site's full host for the active site and variant.SITE\_MAIN\_HOSTstage.example.comThe site's main host, without any variant.CLI invocations
---------------

[](#cli-invocations)

In order to make the same environment variables available for CLI invocations, the package provides the binary `request-matcher-site-variables` which outputs them based upon the set `$SITE` variable. Site variants are not supported in CLI requests, thus SITE\_VARIANT is is always empty.

Usage with Drupal
-----------------

[](#usage-with-drupal)

- Best, invoke the request matcher via the composer autoloader; that makes sure it is invoked very early and has matched requests before anything else goes on. For an example refer to [this](https://github.com/drunomics/drupal-project/blob/4.x/composer.json#L58)

    Be sure your environment variables are set and invoke it like that:

    ```
    $site = drunomics\MultisiteRequestMatcher\RequestMatcher::getInstance()
      ->match();

    ```
- Add the following line to Drupal's sites.php such that Drupal can pick up the matched site. The site name of the APP\_SITES variable should match the Drupal site directory names:

    ```
    $sites[$request->getHost()] = getenv('SITE');

    ```
- Remove any trusted host patterns from Drupal as the request matcher already checked it.

Credits
-------

[](#credits)

developed by drunomics GmbH, Please refer to the commit log individual contributors.

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance51

Moderate activity, may be stable

Popularity28

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 65.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 ~77 days

Recently: every ~249 days

Total

20

Last Release

1137d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/132232?v=4)[Wolfgang Ziegler](/maintainers/fago)[@fago](https://github.com/fago)

---

Top Contributors

[![fago](https://avatars.githubusercontent.com/u/132232?v=4)](https://github.com/fago "fago (29 commits)")[![pagachdrunomics](https://avatars.githubusercontent.com/u/45197243?v=4)](https://github.com/pagachdrunomics "pagachdrunomics (7 commits)")[![petarbasic](https://avatars.githubusercontent.com/u/52317999?v=4)](https://github.com/petarbasic "petarbasic (3 commits)")[![mostepaniukvm](https://avatars.githubusercontent.com/u/15616007?v=4)](https://github.com/mostepaniukvm "mostepaniukvm (2 commits)")[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (2 commits)")[![peterserfozo](https://avatars.githubusercontent.com/u/22172388?v=4)](https://github.com/peterserfozo "peterserfozo (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/drunomics-multisite-request-matcher/health.svg)

```
[![Health](https://phpackages.com/badges/drunomics-multisite-request-matcher/health.svg)](https://phpackages.com/packages/drunomics-multisite-request-matcher)
```

###  Alternatives

[illuminate/cookie

The Illuminate Cookie package.

224.3M120](/packages/illuminate-cookie)[codefog/contao-news_categories

News Categories bundle for Contao Open Source CMS

3183.3k6](/packages/codefog-contao-news-categories)[netgen/content-browser

Netgen Content Browser is a Symfony bundle that provides an interface which selects items from any kind of backend and returns the IDs of selected items back to the calling code.

14112.1k8](/packages/netgen-content-browser)[leapt/core-bundle

Symfony LeaptCoreBundle

2529.1k4](/packages/leapt-core-bundle)[robole/sulu-ai-translator-bundle

Translate any type of content using DeepL

181.3k](/packages/robole-sulu-ai-translator-bundle)[numero2/contao-storelocator

Contao Plugin for managing stores (or in common address data) and providing a frontend-search based on geo data

121.5k](/packages/numero2-contao-storelocator)

PHPackages © 2026

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