一个Laravel包,让您控制使用哪个数据库以及何时切换,无需进行微管理(也适用于广播、缓存、文件系统、日志和队列连接)

0.3.2 2022-01-01 18:04 UTC

This package is auto-updated.

Last update: 2024-08-29 05:28:09 UTC


README

Latest Version on Packagist PHP Version Laravel GitHub Workflow Status Buy The World a Tree Contributor Covenant

code-distortion/swap-con 是一个Laravel包,让您控制使用哪个 数据库 以及何时切换。

示例

// swap the database connection for the duration of the callback
SwapCon::swapDB('mysql2', $callback); // or ->swapDatabase(..)

实际上,SwapCon 还允许您更改 广播缓存文件系统日志队列 连接。

您是否曾想在实际运行时更改Laravel中的数据库连接,但发现很难实现?

您可能尝试过一些方法,但发现它们限制较多

// alter the connection for a particular query
DB::connection('mysql2')->table('users')->all();
// hard-code the connection a model uses
class SomeModel extends Eloquent {
    protected $connection = 'mysql2';
}
// or change the connection for a particular model instance
$someModel = new SomeModel;
$someModel->setConnection('mysql2');
$someModel->find(1);
// specify read/write connections in config/database.php
'mysql' => [
    'read' => [
        'host' => [
            '192.168.1.1',
            '196.168.1.2',
        ],
    ],
    'write' => [
        'host' => [
            '196.168.1.3',
         ],
    ],
    'sticky'    => true,
    'driver'    => 'mysql',
    'database'  => 'database',
    …
],

SwapCon 是这些方法的替代方案。

安装

通过composer安装此包

composer require code-distortion/swap-con

服务提供者与外观注册

SwapCon 利用Laravel 5.5+的自动包检测功能自动与Laravel集成。对于Laravel 5.0 - 5.4,请将以下行添加到config/app.php

'providers' => [
    …
    CodeDistortion\SwapCon\SwapConServiceProvider::class,
    …
],
'aliases' => [
    …
    'SwapCon' => CodeDistortion\SwapCon\SwapConFacade::class,
    …
],

配置文件

使用以下命令发布config/code-distortion.swapcon.php配置文件

php artisan vendor:publish --provider="CodeDistortion\SwapCon\SwapConServiceProvider" --tag="config"

使用方法

SwapCon 使 SwapCon 外观可用于使用。

有两种主要方法来更改连接。您可以在切换默认数据库连接时运行回调(稍后再次替换原始连接),或者您可以使用新的连接继续使用。

通过更改默认连接,您的代码将开始与这个新连接交互,而无需进行微管理。

// swap the current database connection for the duration of the callback
SwapCon::swapDB('mysql2', $callback); // or ->swapDatabase(..)

注意: swap 方法会捕获并重新抛出异常,确保再次替换原始连接,这样您就不必这样做。这是在连接之间切换的最安全方式。

您还可以简单地更改默认数据库以使用

// change the current database
SwapCon::useDB('mysql2'); // or ->useDatabase(..)

您也可以使用这些方法管理其他连接类型

// swap the current connections for the duration of the callback
SwapCon::swapBroadcast('pusher2', $callback);
SwapCon::swapCache('redis2', $callback);
SwapCon::swapFilesystem('s3-2', $callback);
SwapCon::swapLog('syslog', $callback);
SwapCon::swapQueue('sqs2', $callback);

// change the current connection
SwapCon::useBroadcast('pusher2');
SwapCon::useCache('redis2');
SwapCon::useFilesystem('s3-2');
SwapCon::useLog('syslog');
SwapCon::useQueue('sqs2');

这可能是您需要的所有功能。下面是关于如何进一步使用SwapCon的详细信息。

自定义连接

想象一下这种情况,您想在代码的特定部分连接到只读副本数据库。也许您希望将一些重查询卸载到读写数据库以释放资源。

您可以从添加第二个连接到 configs/database.php 开始

// config/database.php
'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '192.168.1.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'mydb_rw'),
    …
],
'mysql-ro' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '192.168.1.2'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'mydb_ro'),
    …
],

并且可以动态切换到此连接

SwapCon::swapDB('mysql-ro', $callback);

然而,您的本地开发环境可能没有像生产环境中那样的副本数据库。

SwapCon 允许您从 .env 文件中任意定义 自定义连接,允许您选择在不同环境中定义哪些连接,如果有的话。

在您的 .env 文件中按照以下格式指定新连接的值

SWAPCON_<CONNECTION-TYPE>_<CONNECTION-NAME>_<SETTING-NAME>=value

("CONNECTION-TYPE" 是以下之一: BROADCASTING, CACHE, DATABASE, FILESYSTEMS, LOGGINGQUEUE).

您还可以选择复制现有连接的设置,并覆盖特定值(如数据库名称或主机)。

例如,下面的新 'mysql-ro1' 连接将采用现有的 'mysql' 连接设置,但覆盖要连接的数据库名称

# .env
SWAPCON__DATABASE__MYSQL-RO1__CLONE=mysql
SWAPCON__DATABASE__MYSQL-RO1__DATABASE=mydb_ro

这还没有比直接在配置文件中添加连接提供更多的功能。然而,您可以通过连接组再进一步...

连接组

您可以使用连接组将多个连接组合在一起。使用以下格式在您的.env文件中定义组:

SWAPCON_GROUP_<CONNECTION-TYPE>_<GROUP-NAME>=<connections>

(其中 "CONNECTION-TYPE" 是以下之一: BROADCASTINGCACHEDATABASEFILESYSTEMSLOGGINGQUEUE)。

例如。

# .env
SWAPCON__GROUP__DATABASE__MYSQL-RO=mysql-ro1,mysql-ro2,mysql-ro3

SWAPCON__DATABASE__MYSQL-RO1__CLONE=mysql
SWAPCON__DATABASE__MYSQL-RO1__DATABASE=mydb_ro1

SWAPCON__DATABASE__MYSQL-RO2__CLONE=mysql
SWAPCON__DATABASE__MYSQL-RO2__DATABASE=mydb_ro2

SWAPCON__DATABASE__MYSQL-RO3__CLONE=mysql
SWAPCON__DATABASE__MYSQL-RO3__DATABASE=mydb_ro3

现在您突然有了3个只读数据库连接,并可以使用名称 'mysql-ro' 来引用它们。

SwapCon::SwapDB('mysql-ro', $callback);

当SwapCon找到组时,它将从中随机选择一个连接。如果再次使用该组,它将继续使用之前选择的同一连接。在这个例子中,SwapCon可能最终选择 'mysql-ro2' 连接。

注意: SwapCon 不会强制实施数据库连接的只读性。

备用连接

现在,如果您在生产中使用了这些只读数据库的一些,但在本地开发环境中没有,那么上面的代码将为您生成一个异常,因为您没有定义 'mysql-ro' 连接或组。

这就是备用连接发挥作用的地方。您可以在 config/code-distortion.swapcon.php 中指定备用连接,以便在找不到连接时使用。

// config/code-distortion.swapcon.php
'fallbacks' => [
    'reuse' => [
        'database' => [
            'mysql-ro' => 'mysql',
        ],
    ],
    'clone' => [
        'database' => [
//            'mysql-ro' => 'mysql',
        ],
    ],
],

在这里,您可以为需要时简单地重用指定一个连接。在这个例子中,'mysql' 连接将继续被使用,除非当前 .env 文件中存在 'mysql-ro' 连接或组。

或者,您可以选择在需要时克隆一个连接。如果上面的行取消注释,则 'mysql' 连接详情将被克隆,并将创建到同一数据库的单独新连接(除非当前 .env 文件中存在 'mysql-ro' 连接或组)。

注意: 根据经验,您应该为代码中按名称引用的每个连接添加一个备用连接。这将在连接无法解析时避免异常的发生。

动态更改可用连接

有时您需要从代码内部更改连接设置。例如,如果您有一个连接到不同数据库的网站,每个客户一个数据库,您可能需要这样做。您的代码需要首先运行以确定需要哪个客户,然后选择其数据库连接。

您可以更改连接

// some code to detect the tenant to use…
$tenantDB = 'client1';

// create a new connection called 'tenant' by cloning the 'mysql' connection, and override the 'database' value
SwapCon::cloneDB('mysql', 'tenant', ['database' => $tenantDB]);
// (allow for the 'tenant' connection to be overwritten if it already exists)
SwapCon::cloneDB('mysql', 'tenant', ['database' => $tenantDB], true);

// then you can access the new 'tenant' connection like any other. eg.
SwapCan::swapDB('tenant', $callback);
SwapCan::useDB('tenant');
DB::connection('tenant')->table('users')->all();
// etc…

或者您可以更新现有的连接

SwapCon::updateDB('tenant', ['database' => $tenantDB]);

注意: 该库的目的是帮助您管理连接,而不是帮助管理租户选择过程。您需要自己确定要使用的租户数据库。

测试

composer test

变更日志

有关最近更改的更多信息,请参阅变更日志

SemVer

该库使用SemVer 2.0.0 版本控制。这意味着对 X 的更改表示破坏性更改:0.0.X0.X.yX.y.z。当该库更改为版本 1.0.0、2.0.0 等时,并不一定表示它是一个值得注意的版本,它只是表示更改是破坏性的。

Treeware

此包是Treeware。如果您在生产中使用它,我们要求您为我们买一棵树以感谢我们的工作。通过为 Treeware 森林做出贡献,您将为当地家庭创造就业机会并恢复野生动物栖息地。

贡献

有关详细信息,请参阅贡献

行为准则

有关详细信息,请参阅行为准则

安全性

如果您发现任何与安全相关的问题,请通过电子邮件tim@code-distortion.net联系我们,而不是使用问题跟踪器。

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件

PHP包模板

此包使用PHP包模板生成。