PHPackages                             wronx/multitenancy-bundle - 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. [Framework](/categories/framework)
4. /
5. wronx/multitenancy-bundle

ActiveSymfony-bundle[Framework](/categories/framework)

wronx/multitenancy-bundle
=========================

Poor Man's MultiTenancy for Symfony

v0.9-RC1(8y ago)318WTFPLPHP

Since Jul 19Pushed 8y ago3 watchersCompare

[ Source](https://github.com/WRonX/Symfony-MultiTenancyBundle)[ Packagist](https://packagist.org/packages/wronx/multitenancy-bundle)[ RSS](/packages/wronx-multitenancy-bundle/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (2)Versions (2)Used By (0)

#### Poor Man's Symfony Multitenancy Bundle

[](#poor-mans-symfony-multitenancy-bundle)

This piece of poorly written code may help you with creating multi-tenant applications in Symfony. Or may not. I don't know, I'm a plumber, not a fortune-teller.

#### License:

[](#license)

> Copyright © 2017 github.com/WRonX This work is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See  for more details.

#### Features:

[](#features)

Just one: you can enable multi-tenant architecture in your application.

#### How it works

[](#how-it-works)

I couldn't think of better solution, so every tenant has a name and host, by which it's identified. Name is used to identify tenant when using Symfony console, host for everything else. In general, `ConnectionWrapper` changes `Connection` database, depending on currently used host.

> **NOTE:** In performance matter, this is probably not the best idea for bigger applications and **you probably should cache Connection somehow to prevent it from making tenant identifying SQL request every time it's created.** But what do I know.

#### Installation and Configuration:

[](#installation-and-configuration)

##### 1. Installing the bundle

[](#1-installing-the-bundle)

First, install the bundle with `composer`:

```
composer require wronx/multitenancy-bundle

```

Then add the bundle to `AppKernel`:

```
// app/AppKernel.php

$bundles = array( /* ... */
            new WRonX\MultiTenancyBundle\WRonXMultiTenancyBundle(),

```

And add the following do your `config.yml`:

```
# app/config/config.yml

wronx_multitenancy:
    enabled: true

```

If you skip the last step, multitenancy will be disabled by default.

> **NOTE:** With disabled multitenancy, your application uses the main (described in `parameters.yml`) database in normal way.

The following steps are assuming multitenancy is enabled.

##### 2. Prepare Tenant Manager database:

[](#2-prepare-tenant-manager-database)

First, create database, which will serve as Tenant Manager. That means connection details will be stored there. Passwords will be stored in plaintext, just like DB password in `parameters.yml`. The `parameters.yml` connection details should point to Tenant Manager database. Now, Tenant Manager database should contain `tenants` table with connection details for every tenant:

```
mysql> SHOW COLUMNS FROM tenants;
+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| id     | int(11)      | NO   | PRI | NULL    | auto_increment |
| name   | varchar(255) | YES  |     | NULL    |                |
| host   | varchar(255) | YES  |     | NULL    |                |
| dbName | varchar(255) | YES  |     | NULL    |                |
| dbPass | varchar(255) | YES  |     | NULL    |                |
| dbUser | varchar(255) | YES  |     | NULL    |                |
| dbHost | varchar(255) | YES  |     | NULL    |                |
| active | tinyint(1)   | YES  |     | NULL    |                |
+--------+--------------+------+-----+---------+----------------+

```

As `ConnectionWrapper` uses `REGEXP`, **host field** can look like the following:

- `.*`
- `^(.*\.)*client01\.yourapplicationdomain\.com$`
- `^((.*\.)*client02\.yourapplicationdomain\.com)|(clientsowndomain\.com)$`

As you can see from this example, you can handle multime client domains, and subdomains can be ignored. Also, `SELECT` query is ordered by host field's length (descending), so every request to non-existing host (tenant) will be handled by connection data defined in record with `.*` host, which can be useful for creating demo environment. Many thanks to [swiniak](https://github.com/swiniak/) for coming up with `REGEXP` idea.

##### 2. Using included code and configuration:

[](#2-using-included-code-and-configuration)

This should be self-explanatory.

##### 3. Using Symfony console:

[](#3-using-symfony-console)

Just remember to add tenant name for every command, using `--tenant=TENANTNAME` (this is the *name* field from `tenants` table).

##### 4. New console commands

[](#4-new-console-commands)

Two new console commands were added:

- `tenants:list` just shows available tenant names (and some additional data)
- `tenants:execute "command to execute"` executes given (quoted!) command on all tenants. Example: `php app/console tenants:execute "doctrine:schema:update --dump-sql"`

#### Changes coming soon

[](#changes-coming-soon)

- adding console commands to automatically create tenants table and manage tenants
- changing ignored commands list into commands whitelist

#### Summary

[](#summary)

Oh, come on, I spent enough time writing readme already...

###  Health Score

24

—

LowBetter than 31% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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

Unknown

Total

1

Last Release

3265d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2788306?v=4)[WRonX](/maintainers/WRonX)[@WRonX](https://github.com/WRonX)

---

Top Contributors

[![WRonX](https://avatars.githubusercontent.com/u/2788306?v=4)](https://github.com/WRonX "WRonX (19 commits)")

---

Tags

symfonybundletenantmultitenancymultitenant

### Embed Badge

![Health badge](/badges/wronx-multitenancy-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/wronx-multitenancy-bundle/health.svg)](https://phpackages.com/packages/wronx-multitenancy-bundle)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M196](/packages/sulu-sulu)[nunomazer/laravel-samehouse

A multi-tenant Laravel package, based on single database, simple and ease to use

24250.7k](/packages/nunomazer-laravel-samehouse)[orbitale/cms-bundle

A simple lightweight CMS bundle for Symfony

6343.4k](/packages/orbitale-cms-bundle)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1615.6k12](/packages/2lenet-crudit-bundle)

PHPackages © 2026

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