数据库配置

Testing Is Documentation

tests/Database/ManagerTest.php数据库配置 - 图1

我们可以在 option/database.php 文件中定义数据库连接。

Uses

  1. <?php
  2. use PDO;
  3. use Tests\Database\DatabaseTestCase as TestCase;

基本配置

数据库配置基本定义功能展示。

数据库配置

  1. # Tests\Database::createDatabaseManager
  2. protected function createDatabaseManager(): Manager
  3. {
  4. $container = new Container();
  5. $manager = new Manager($container);
  6. $this->assertInstanceof(IContainer::class, $manager->container());
  7. $this->assertInstanceof(Container::class, $manager->container());
  8. $option = new Option([
  9. 'database' => [
  10. 'default' => 'mysql',
  11. 'connect' => [
  12. 'mysql' => [
  13. 'driver' => 'mysql',
  14. 'host' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['HOST'],
  15. 'port' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['PORT'],
  16. 'name' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['NAME'],
  17. 'user' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['USER'],
  18. 'password' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['PASSWORD'],
  19. 'charset' => 'utf8',
  20. 'options' => [
  21. PDO::ATTR_PERSISTENT => false,
  22. PDO::ATTR_CASE => PDO::CASE_NATURAL,
  23. PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
  24. PDO::ATTR_STRINGIFY_FETCHES => false,
  25. PDO::ATTR_EMULATE_PREPARES => false,
  26. PDO::ATTR_TIMEOUT => 30,
  27. ],
  28. 'separate' => false,
  29. 'distributed' => false,
  30. 'master' => [],
  31. 'slave' => [],
  32. ],
  33. 'password_right' => [
  34. 'driver' => 'mysql',
  35. 'password' => $GLOBALS['LEEVEL_ENV']['DATABASE']['MYSQL']['PASSWORD'],
  36. ],
  37. 'password_not_right' => [
  38. 'driver' => 'mysql',
  39. 'password' => 'not right',
  40. ],
  41. ],
  42. ],
  43. 'cache' => [
  44. 'default' => 'file',
  45. 'expire' => 86400,
  46. 'time_preset' => [],
  47. 'connect' => [
  48. 'file' => [
  49. 'driver' => 'file',
  50. 'path' => __DIR__.'/databaseCacheManager',
  51. 'expire' => null,
  52. ],
  53. 'redis' => [
  54. 'driver' => 'redis',
  55. 'host' => $GLOBALS['LEEVEL_ENV']['CACHE']['REDIS']['HOST'],
  56. 'port' => $GLOBALS['LEEVEL_ENV']['CACHE']['REDIS']['PORT'],
  57. 'password' => $GLOBALS['LEEVEL_ENV']['CACHE']['REDIS']['PASSWORD'],
  58. 'select' => 0,
  59. 'timeout' => 0,
  60. 'persistent' => false,
  61. 'expire' => null,
  62. ],
  63. ],
  64. ],
  65. ]);
  66. $container->singleton('option', $option);
  67. $eventDispatch = $this->createMock(IDispatch::class);
  68. $this->assertNull($eventDispatch->handle('event'));
  69. $container->singleton(IDispatch::class, $eventDispatch);
  70. $cache = $this->createCacheManager($container, $option, 'file');
  71. $container->singleton('caches', $cache);
  72. $this->databaseConnects[] = $manager->connect();
  73. return $manager;
  74. }

请使用这样的格式来定义连接,系统会自动帮你访问数据库。 系统底层实质上会使用 \Leevel\Option\Option 来管理配置信息。

  1. public function testBaseUse(): void
  2. {
  3. $manager = $this->createDatabaseManager();
  4. $data = ['name' => 'tom', 'content' => 'I love movie.'];
  5. $this->assertSame(
  6. 1,
  7. $manager
  8. ->table('guest_book')
  9. ->insert($data)
  10. );
  11. $result = $manager->table('guest_book', 'name,content')
  12. ->where('id', 1)
  13. ->findOne();
  14. $this->assertSame('tom', $result->name);
  15. $this->assertSame('I love movie.', $result->content);
  16. }

数据库主从设置

QueryPHP 允许用户一个主数据库作为写入、更新以及删除,外加多个附属从数据库作为只读数据库来共同提供数据库服务。 多个数据库需要需要开启 distributed,而 separate 主要用于读写分离。 master 为主数据库,slave 为附属从数据库设置。

  1. public function testParseDatabaseOptionDistributedIsTrue(): void
  2. {
  3. $manager = $this->createDatabaseManager();
  4. $option = [
  5. 'driver' => 'mysql',
  6. 'host' => '127.0.0.1',
  7. 'port' => 3306,
  8. 'name' => 'test',
  9. 'user' => 'root',
  10. 'password' => '123456',
  11. 'charset' => 'utf8',
  12. 'options' => [
  13. PDO::ATTR_PERSISTENT => false,
  14. PDO::ATTR_CASE => PDO::CASE_NATURAL,
  15. PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
  16. PDO::ATTR_STRINGIFY_FETCHES => false,
  17. PDO::ATTR_EMULATE_PREPARES => false,
  18. PDO::ATTR_TIMEOUT => 30,
  19. ],
  20. 'separate' => false,
  21. 'distributed' => true,
  22. 'master' => [],
  23. 'slave' => ['host' => '127.0.0.1'],
  24. ];
  25. $optionNew = $this->invokeTestMethod($manager, 'normalizeDatabaseOption', [$option]);
  26. $data = <<<'eot'
  27. {
  28. "driver": "mysql",
  29. "separate": false,
  30. "distributed": true,
  31. "master": {
  32. "host": "127.0.0.1",
  33. "port": 3306,
  34. "name": "test",
  35. "user": "root",
  36. "password": "123456",
  37. "charset": "utf8",
  38. "options": {
  39. "12": false,
  40. "8": 0,
  41. "11": 0,
  42. "17": false,
  43. "20": false,
  44. "2": 30
  45. }
  46. },
  47. "slave": [
  48. {
  49. "host": "127.0.0.1",
  50. "port": 3306,
  51. "name": "test",
  52. "user": "root",
  53. "password": "123456",
  54. "charset": "utf8",
  55. "options": {
  56. "12": false,
  57. "8": 0,
  58. "11": 0,
  59. "17": false,
  60. "20": false,
  61. "2": 30
  62. }
  63. }
  64. ]
  65. }
  66. eot;
  67. $this->assertSame(
  68. $data,
  69. $this->varJson($optionNew)
  70. );
  71. }

附属从数据库支持二维数组

从数据库支持多个,支持二维数组

  1. public function testParseDatabaseOptionDistributedIsTrueWithTwoDimensionalArray(): void
  2. {
  3. $manager = $this->createDatabaseManager();
  4. $option = [
  5. 'driver' => 'mysql',
  6. 'host' => '127.0.0.1',
  7. 'port' => 3306,
  8. 'name' => 'test',
  9. 'user' => 'root',
  10. 'password' => '123456',
  11. 'charset' => 'utf8',
  12. 'options' => [
  13. PDO::ATTR_PERSISTENT => false,
  14. PDO::ATTR_CASE => PDO::CASE_NATURAL,
  15. PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
  16. PDO::ATTR_STRINGIFY_FETCHES => false,
  17. PDO::ATTR_EMULATE_PREPARES => false,
  18. PDO::ATTR_TIMEOUT => 30,
  19. ],
  20. 'separate' => false,
  21. 'distributed' => true,
  22. 'master' => [],
  23. 'slave' => [
  24. ['host' => '127.0.0.1'],
  25. ['password' => '123456'],
  26. ],
  27. ];
  28. $optionNew = $this->invokeTestMethod($manager, 'normalizeDatabaseOption', [$option]);
  29. $data = <<<'eot'
  30. {
  31. "driver": "mysql",
  32. "separate": false,
  33. "distributed": true,
  34. "master": {
  35. "host": "127.0.0.1",
  36. "port": 3306,
  37. "name": "test",
  38. "user": "root",
  39. "password": "123456",
  40. "charset": "utf8",
  41. "options": {
  42. "12": false,
  43. "8": 0,
  44. "11": 0,
  45. "17": false,
  46. "20": false,
  47. "2": 30
  48. }
  49. },
  50. "slave": [
  51. {
  52. "host": "127.0.0.1",
  53. "port": 3306,
  54. "name": "test",
  55. "user": "root",
  56. "password": "123456",
  57. "charset": "utf8",
  58. "options": {
  59. "12": false,
  60. "8": 0,
  61. "11": 0,
  62. "17": false,
  63. "20": false,
  64. "2": 30
  65. }
  66. },
  67. {
  68. "password": "123456",
  69. "host": "127.0.0.1",
  70. "port": 3306,
  71. "name": "test",
  72. "user": "root",
  73. "charset": "utf8",
  74. "options": {
  75. "12": false,
  76. "8": 0,
  77. "11": 0,
  78. "17": false,
  79. "20": false,
  80. "2": 30
  81. }
  82. }
  83. ]
  84. }
  85. eot;
  86. $this->assertSame(
  87. $data,
  88. $this->varJson($optionNew)
  89. );
  90. }

数据库设置只支持数组

数据库主从连接只支持数组。

  1. public function testParseDatabaseOptionMasterAndSlaveMustBeAnArray(): void
  2. {
  3. $this->expectException(\InvalidArgumentException::class);
  4. $this->expectExceptionMessage(
  5. 'Database option `slave` must be an array.'
  6. );
  7. $manager = $this->createDatabaseManager();
  8. $option = [
  9. 'driver' => 'mysql',
  10. 'host' => '127.0.0.1',
  11. 'port' => 3306,
  12. 'name' => 'test',
  13. 'user' => 'root',
  14. 'password' => '123456',
  15. 'charset' => 'utf8',
  16. 'options' => [
  17. PDO::ATTR_PERSISTENT => false,
  18. PDO::ATTR_CASE => PDO::CASE_NATURAL,
  19. PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
  20. PDO::ATTR_STRINGIFY_FETCHES => false,
  21. PDO::ATTR_EMULATE_PREPARES => false,
  22. PDO::ATTR_TIMEOUT => 30,
  23. ],
  24. 'separate' => false,
  25. 'distributed' => true,
  26. 'master' => [],
  27. 'slave' => 'notarray',
  28. ];
  29. $this->invokeTestMethod($manager, 'normalizeDatabaseOption', [$option]);
  30. }