tomkyle/databases

通过易于使用的连接工厂创建通用数据库API连接。对于多个数据库,服务定位器可以帮助您创建这些工厂。

1.0.12 2015-01-15 07:49 UTC

This package is auto-updated.

Last update: 2024-09-11 18:10:50 UTC


README

#数据库工厂与服务定位器

此数据库连接工厂与服务定位器创建到常见数据库API的通用连接,这些API由易于使用的连接工厂提供。当与多个数据库一起工作时,服务定位器可以帮助您创建这些工厂。它支持PDOmysqliAura.SQL v1.3

Build Status Scrutinizer Quality Score Coverage Status

##概述 ###单个数据库

  1. 使用关联数组或StdClass设置 DatabaseConfig
  2. 使用配置对象创建 DatabaseProvider(依赖注入)
  3. 为所需的数据库API 获取连接

立即显示!

###多个数据库

  1. 在二维数组或StdClass中描述数据库连接
  2. 使用配置对象设置 DatabaseServiceLocator
  3. 从ServiceLocator获取 DatabaseProvider
  4. 为所需的数据库API 获取连接

立即显示!

##安装

此库除了Fabien Potencier的Pimple库外没有依赖项。它可以通过Composer安装和自动加载。在安装过程中,Composer会建议安装Aura.SQL v1.3,如果您还没有安装。通过命令行或composer.json文件安装

#####命令行

composer require tomykle/databases

#####composer.json "require": { "tomkyle/databases": "~1.0" }

##入门:单个数据库

###概述每个DatabaseProvider都需要一些有关要处理的数据库的信息,这些信息作为实现DatabaseConfigInterface的参数传递。一个现成的实现是DatabaseConfig,它可以通过关联数组或StdClass进行配置。

现在您已经准备好了DatabaseConfig,只需将其传递给新的DatabaseProvider并获取您喜欢的连接即可。

###示例

<?php
use \tomkyle\Databases\DatabaseConfig;
use \tomkyle\Databases\DatabaseProvider;

// 1a. Describe your database as array:
$describe = array(
  'host'     => "localhost",
  'database' => "database1",
  'user'     => "root",
  'pass'     => "secret",
  'charset'  => "utf8"
);

// 1b. Describe your database as StdClass:
$describe = json_decode('{
  "host":     "localhost",
  "database": "database1"
  # etc.
}');

// 2. Setup DatabaseConfig instance:
$config = new DatabaseConfig( $describe );

// 3. Create DatabaseProvider instance:
$factory = new DatabaseProvider( $config );

// 4. Grab Aura.SQL connection:
$aura = $factory->getAuraSql();

###配置选项如果以下字段之一为空或不存在,则DatabaseConfig将抛出RuntimeException

  • host: 主机名
  • database: 数据库名称
  • userusername: 数据库用户
  • passpassword: 数据库密码

可选字段,具有根据MySQL设置的默认值

  • charset: 要使用的字符集,默认为utf8
  • type: 数据库类型,默认为mysql
  • port: 数据库端口,默认为3306

###获取连接

每个DatabaseProvider实例都提供了不同类型的Singleton-like数据库连接。您可以通过调用getter方法或将其作为数组键(Pimple的方式)来获取您的连接。

####PDO连接

$pdo = $factory->getPdo();
// or 
$pdo = $factory['pdo'];

echo get_class( $pdo );
// "PDO"

####Aura.SQL连接

aura = $factory->getAuraSql();
// or 
$aura = $factory['aura.sql'];

echo get_class( $aura );
// "Aura\Sql\Connection\Mysql", for example

// Common configuration afterwards
$aura->setAttribute( \PDO::ATTR_ERRMODE,             \PDO::ERRMODE_EXCEPTION );
$aura->setAttribute( \PDO::ATTR_DEFAULT_FETCH_MODE,  \PDO::FETCH_OBJ);

####mysqli连接

$mysqli = $factory->getMysqli();
// or 
$mysqli = $factory['mysqli'];

echo get_class( $mysqli );
// "mysqli"

##多个数据库:使用服务定位器

假设您的项目处理几个不同的数据库,凭证等信息在一个JSON配置文件中。首先,使用配置选项(见下文完整列表)描述每个连接

#####示例配置文件

{
  "first_db" : {
    "host":     "db_host",
    "database": "db_name",
    "user":     "db_user",
    "pass":     "db_pass"
  },
  "second_db" : {
    "host":     "other_host",
    "database": "other_db",
    "user":     "other_user",
    "pass":     "other_pass",
    "type":     "not_mysql",
    "charset":  "utf8"
  }
}

###用法

  1. 将配置内容解析为StdClass对象
  2. 创建一个新的DatabaseServiceLocator实例,
    传入你的数据库描述
  3. 获取你的数据库的DatabaseProvider实例
  4. 让工厂创建通用的连接
<?php
use \tomkyle\Databases\DatabaseServiceLocator;

$config = json_decode( file_get_contents( 'config.json' ));
$databases = new DatabaseServiceLocator( $config );

// 1. Get DatabaseProvider instance, Pimple-style:
$first_factory = $databases['first_db'];

// 2. Let factory create Aura.SQL connection:
$first_aura = $first_factory->getAuraSql();

###获取连接 在DatabaseServiceLocator中传入的每个数据库都将像数组成员一样可用。返回的数据库将是一个类似Singleton的DatabaseProvider实例。

$foo_factory = $databases['foo_db'];  
echo get_class( $foo_factory );
// "DatabaseProvider"

由于服务定位器和工厂都是Pimple扩展,您也可以在一次调用中获取连接

$databases = new DatabaseServiceLocator( $config );

$first_pdo    = $databases['first_db']->getPdo();
$first_mysqli = $databases['first_db']->getMysqli();
$first_aura   = $databases['first_db']->getAuraSql();

$second_pdo    = $databases['second_db']['pdo'];
$second_mysqli = $databases['second_db']['mysqli'];
$second_aura   = $databases['second_db']['aura.sql'];

##最佳实践 如果一个类需要特殊的数据库连接,比如说PDO,可以这样做

  1. 获取你的连接提供者
  2. 让它为你创建一个PDO连接
  3. 注入生成的PDO。

…下一个依赖Aura.SQL的类

  1. 使用相同的连接提供者实例(记住:Singleton!)
  2. 让它为你创建一个Aura.SQL连接
  3. 注入生成的Aura.SQL MySQL连接。

这样,当事情出错时,它们会在你的业务类之外出错(控制反转)。

Paul M. Jones最近在他的新发表的“应用程序层DI容器应该在哪里?”文章中介绍了这个话题。

##问题和答案

###等等,这不是一个反模式吗? 是的,如果你在类中使用DatabaseServiceLocator作为依赖项,在构造函数或Setter方法中注入它,或者对其进行类型提示,或者不这样做。不是,如果你在你的组合根或配置环境中使用它。

###连接配置有多远?除了它们的字符集之外,“工厂外”的连接没有进行特殊配置。所以如果你喜欢更改默认的fetch模式或(想想PDO::setAttribute),你可能需要自己配置它。记住,每个连接都是通用的!

###关于Aura.SQL v2?目前,DatabaseServiceLocator支持Aura.SQL v1.3。随着Aura v2的即将到来,Aura.SQL被拆分为三个模块Aura.SQL v2 Aura.SQL_QueryAura.SQL_Schema - 请参阅Paul M. Jones的文章“一瞥Aura v2 -- Aura.Sql和ExtendedPdo”

我将尽快添加v2支持,一旦v2变得稳定或成为标准,并且我习惯了它。如果你已经习惯了,欢迎你fork自己的DatabaseServiceLocator :-)