Repository navigation
Add setInstance() support for runtime database switching #9812
Description
PHP Version
8.3
CodeIgniter4 Version
4.6.1
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
apache
Database
MySQL
What happened?
I would like to request a new method in Config\Database that allows developers to set or override a database connection instance at runtime without modifying the framework core.
This is especially useful when a project needs dynamic database switching, such as in:
Multi-tenant SaaS applications
ERP systems with client-specific databases
“Switch DB per request” API requirements
Dynamic “connect with custom credentials” scenarios
Currently, CodeIgniter 4 allows Database::connect($group) but there is no official method to replace or inject a database instance for a given group.
Proposed Method
Add this method in system/Database/Config.php:
public static function setInstance(string $group, array $config)
{
static::ensureFactory();
$connection = static::$factory->load($config, $group);
static::$instances[$group] = $connection;
return $connection;
}
Why this is needed
Today, Database::connect() always loads config from app/Config/Database.php.
To use a custom connection (hostname, username, password, database), we must create a fake group name or override config objects — both are hacky.
Dynamic DB switching is common in modern SaaS, ERP, and enterprise applications.
This addition would provide a clean, supported API for runtime DB instance control.
Example Use Case
$dbConfig = [
'DSN' => '',
'hostname' => $tenantHost,
'username' => $tenantUser,
'password' => $tenantPass,
'database' => $tenantDb,
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
];
$connection = \Config\Database::setInstance('tenant', $dbConfig);
$db = \Config\Database::connect('tenant');
This gives developers the power to switch databases safely and officially.
Backward Compatibility
This method does not change any existing behavior.
It only adds a new optional utility method.
No BC breaks.
Conclusion
This feature will make CodeIgniter 4 significantly more flexible for advanced and enterprise applications that require dynamic DB switching.
Thank you for considering this enhancement! 🙏
Steps to Reproduce
I would like to request a new method in Config\Database that allows developers to set or override a database connection instance at runtime without modifying the framework core.
This is especially useful when a project needs dynamic database switching, such as in:
Multi-tenant SaaS applications
ERP systems with client-specific databases
“Switch DB per request” API requirements
Dynamic “connect with custom credentials” scenarios
Currently, CodeIgniter 4 allows Database::connect($group) but there is no official method to replace or inject a database instance for a given group.
Proposed Method
Add this method in system/Database/Config.php:
public static function setInstance(string $group, array $config)
{
static::ensureFactory();
$connection = static::$factory->load($config, $group);
static::$instances[$group] = $connection;
return $connection;
}
Why this is needed
Today, Database::connect() always loads config from app/Config/Database.php.
To use a custom connection (hostname, username, password, database), we must create a fake group name or override config objects — both are hacky.
Dynamic DB switching is common in modern SaaS, ERP, and enterprise applications.
This addition would provide a clean, supported API for runtime DB instance control.
Example Use Case
$dbConfig = [
'DSN' => '',
'hostname' => $tenantHost,
'username' => $tenantUser,
'password' => $tenantPass,
'database' => $tenantDb,
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
];
$connection = \Config\Database::setInstance('tenant', $dbConfig);
$db = \Config\Database::connect('tenant');
This gives developers the power to switch databases safely and officially.
Backward Compatibility
This method does not change any existing behavior.
It only adds a new optional utility method.
No BC breaks.
Conclusion
This feature will make CodeIgniter 4 significantly more flexible for advanced and enterprise applications that require dynamic DB switching.
Thank you for considering this enhancement! 🙏
Expected Output
I would like to request a new method in Config\Database that allows developers to set or override a database connection instance at runtime without modifying the framework core.
This is especially useful when a project needs dynamic database switching, such as in:
Multi-tenant SaaS applications
ERP systems with client-specific databases
“Switch DB per request” API requirements
Dynamic “connect with custom credentials” scenarios
Currently, CodeIgniter 4 allows Database::connect($group) but there is no official method to replace or inject a database instance for a given group.
Proposed Method
Add this method in system/Database/Config.php:
public static function setInstance(string $group, array $config)
{
static::ensureFactory();
$connection = static::$factory->load($config, $group);
static::$instances[$group] = $connection;
return $connection;
}
Why this is needed
Today, Database::connect() always loads config from app/Config/Database.php.
To use a custom connection (hostname, username, password, database), we must create a fake group name or override config objects — both are hacky.
Dynamic DB switching is common in modern SaaS, ERP, and enterprise applications.
This addition would provide a clean, supported API for runtime DB instance control.
Example Use Case
$dbConfig = [
'DSN' => '',
'hostname' => $tenantHost,
'username' => $tenantUser,
'password' => $tenantPass,
'database' => $tenantDb,
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
];
$connection = \Config\Database::setInstance('tenant', $dbConfig);
$db = \Config\Database::connect('tenant');
This gives developers the power to switch databases safely and officially.
Backward Compatibility
This method does not change any existing behavior.
It only adds a new optional utility method.
No BC breaks.
Conclusion
This feature will make CodeIgniter 4 significantly more flexible for advanced and enterprise applications that require dynamic DB switching.
Thank you for considering this enhancement! 🙏
Anything else?
No response
Activity
lonnieezell commentedon Nov 28, 2025
Among the several possible ways to connect to the database you can already specify custom config values when you create a connection, see Connecting with Custom Settings.
The group specifies the connection values already so adding custom values to completely replace all of the values in the configuration array doesn't make sense. I can see it making sense to allow setting override values when specifying the group name, since the most common use case that I can think of is a very large app with multiple databases of the same type. However, I don't know how common that is and if it needs to be in core since it's simple enough for an app handle that override with 2 lines of code, like:
I'd be interested to see what others have to say, though.
P.S. - maybe take the time to clean up your request - you seem to have multiple versions of the same request back to back....
neznaika0 commentedon Nov 28, 2025
I don't work with frequent DB switching. I don't understand why not use groups. It looks the same
[-]Bug: . 🚀 Feature Request: Add setInstance() support for runtime database switching in CodeIgniter 4[/-][+]Add setInstance() support for runtime database switching[/+]michalsn commentedon Nov 28, 2025
I have never used a separate database connection per tenant, but are you sure you need to change the entire connection?
I would expect that tenants would share the same server, and just the database name would be changing. In that case, we already have
setDatabase()method in theConnectionclass. Although I can imagine the need for a separate connection due to different credentials per tenant.Honestly, since you have to load database credentials from somewhere - probably the master database? Then I would consider using Registrars to seed the
tenantgroup array, which would be defined in the config (as an empty one). Then, in your code, you could just use thetenantconnection group.brillsense-shailesh commentedon Nov 29, 2025
🔍 Clarification of My Use Case (Why
setInstance()Is Needed)Thank you for the feedback. Let me clarify my scenario, because my requirement cannot be solved by:
Database::connect(configArray)setDatabase()My project is a Large-Scale Multi-Tenant SaaS CRM built in CodeIgniter 4 + HMVC with the following structure:
✔ 1. Each Application (Module) is a Separate Product
In my CRM, I can create multiple applications/products, and each application has:
Example:
✔ 2. Each Application Has Multiple Clients (Multi-Tenant Per App)
Every client who buys a subscription for a particular application (project) gets their own separate database, not just a different schema name.
Example:
➡️ Each client = separate database server OR database credentials.
✔ 3. DB Groups Cannot Be Predefined
I cannot define fixed groups in
app/Config/Database.phpbecause:Defining 500 DB groups dynamically is not reasonable.
✔ 4. Why Current Solution Doesn't Work
❌ “Use Connect With Config Array”
Yes, I can do:
But this does not register the connection inside
Database::$instances[$group].My entire project uses:
When switching tenants, I need:
Database::$instances.Without
setInstance(), CI4 will still try to load fromConfig\Database.php.❌ “Use setDatabase()”
This only changes the database name inside the same connection.
But in my case:
So new connection is mandatory per tenant.
❌ “Use Registrars to seed groups”
Not possible because tenant DB details are generated:
I cannot generate groups on boot.
✔ 5. Why
setInstance()Is Perfect for My Use CaseI want to do:
This allows:
This mirrors patterns in other modern frameworks (Laravel, Symfony).
✔ 6. Summary of Why I Really Need This Feature
$groupDatabase::$instancesWithout
setInstance(), I must hack into protected properties or override core classes — which I want to avoid.🙏 Final Note
My goal is not to replace or conflict with existing features; I only want a clean, framework-supported way to inject database instances at runtime for multitenant SaaS systems.
Thank you for considering this enhancement. I believe many enterprise-level CI4 applications will benefit from this small but powerful feature.
michalsn commentedon Nov 29, 2025
That is not true. The entry in the database instances is always created. It just has a different naming convention.
The main problem I have with this approach is that it will not work as expected when we call for a "none shared" instance.