当我使用包装类尝试类似的操作时,我遇到了 PHP API 平台中的多租户问题:
doctrine:
dbal:
connections:
default:
wrapper_class: App\Doctrine\TenantConnection
driver: pdo_mysql
host: '%env(resolve:DATABASE_HOST)%'
port: 3306
user: '%env(resolve:DATABASE_USER)%'
password: '%env(resolve:DATABASE_PASSWORD)%'
charset: UTF8MB4
class TenantConnection extends Connection
{
public function __construct(array $params, $driver, $config)
{
$tenantId = $_SERVER['HTTP_TENANT_ID'] ?? null;
$dbName = // get by $tenantId from json (simply)
$params['dbname'] = $dbName; // dynamic change of DB Name
try {
parent::__construct($params, $driver);
} catch(ConnectionException $e) {
}
}
}
当我在本地运行它时,一切正常。但是,当我将 Dockerfile 构建到 GKE 时,它失败了,因为未定义
$_SERVER['HTTP_TENANT_ID']
(在某些实验中,当我尝试调用返回 $_SERVER['HTTP_TENANT_ID']
的控制器时,一切都很好并且存在)。
Caddy/Franken 制作有问题吗?我认为它将所有容器加载到缓存中,因此所有 http 请求都会更快。但如何修改我的多租户实验才能使其发挥作用呢?或者这是不好的做法?我想避免有多个后端,其中唯一的更改是 dbName(来自 env)。感谢您的帮助。
参数应该是私有的。 您必须初始化新连接
public function changeDatabase(Tenant $tenant): bool
{
$params = $this->getParams();
if ($params['dbname'] !== $tenant->getDatabaseParam()->getName()) {
if ($this->isConnected()) {
$this->close();
}
$params['url'] = "postgresql://" . $params['user'] . ":" . $params['password'] . "@" . $params['host'] . ":" . $params['port'] . "/" . $tenant->getDatabaseParam()->getName(
);
$params['dbname'] = $tenant->getDatabaseParam()->getName();
parent::__construct(
$params,
$this->_driver,
$this->_config,
$this->_eventManager
);
return true;
}
return false;
}