【发布时间】:2022-07-15 13:31:44
【问题描述】:
我正在尝试使用 Codeigniter4 构建多租户 saas 应用程序。我想为每个 tanent 的数据设置单独的数据库,为用户设置一个全局数据库。
我希望应用程序根据登录用户的 tanent id 自动切换到 tanent 的数据库。为此,我已经确定了 tanents 子域,如下所示
app/config/constants.php
if(!defined('myHostName')){
$sd=explode(".",$_SERVER['HTTP_HOST']);
//define('myHostName', $host);
if($sd[0]=='localhost')
define('dbname', 'defaultdb');
else
define('dbname', $sd[0]);
如果调用来自子域,这些代码标识子域并将 dbname 定义为子域的名称。然后我在 app/config/database.php 中定义了两个数据库组如下。
public $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'db_blog',
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
];
public $data = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => myHostName,
'DBDriver' => 'MySQLi',
'DBPrefix' => '',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8',
'DBCollat' => 'utf8_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
];
这工作正常,但现在我希望根据域上的文件夹动态选择数据库,例如
租户 1 的 baseurl 将是 https://example.com/tenant1
租户 2 的 baseurl 将是 https://example.com/tenant2
租户 3 的 baseurl 将是 https://example.com/tenant3
这里的问题是第一段(在本例中为tenant1/tenant2/tenant3)被codeigniter4识别为控制器,我假设必须有一些方法来识别站点url上的文件夹名称
或解决方案可能类似于https://www.sandeeprajoria.in/2013/05/multi-tenancy-with-codeigniter.html
【问题讨论】:
-
我必须假设,因为您的链接没有命名控制器,您的服务上只有一个控制器。在这种情况下,您可以将其设置为默认控制器,然后使用 URL 助手获取 url 的第一段并选择您的数据库。如果您确实有多个控制器,我建议您更改您的 url 以匹配 CodeIgniter 期望的模式。如果做不到这一点,你或许可以用路由做一些魔法来得到你想要的。
-
您可以做到这一点的一种方法是将所有路由分组并使用段替换,然后由一个负责更改数据库并引发错误的中间件跟进。
-
@Jerry 这是为了明确应用程序没有使用单个控制器。
标签: php multi-tenant saas codeigniter-4