{"id":18783691,"url":"https://github.com/tomkyle/databases","last_synced_at":"2025-12-20T18:30:17.914Z","repository":{"id":13987937,"uuid":"16688946","full_name":"tomkyle/Databases","owner":"tomkyle","description":"Creates generic connections to common database APIs, provided by easy-to-use connection factories. When working with multiple databases, a Service Locator helps you creating those factories. Pimple-powered.","archived":false,"fork":false,"pushed_at":"2015-01-15T07:50:01.000Z","size":692,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-29T11:45:36.683Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomkyle.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-10T08:26:44.000Z","updated_at":"2015-01-15T07:49:58.000Z","dependencies_parsed_at":"2022-09-22T14:41:25.066Z","dependency_job_id":null,"html_url":"https://github.com/tomkyle/Databases","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2FDatabases","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2FDatabases/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2FDatabases/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomkyle%2FDatabases/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomkyle","download_url":"https://codeload.github.com/tomkyle/Databases/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239699579,"owners_count":19682574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T20:40:08.644Z","updated_at":"2025-12-20T18:30:17.823Z","avatar_url":"https://github.com/tomkyle.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"#Databases Factory \u0026 Service Locator  \n\nThis Databases Connection Factory \u0026 Service Locator creates generic connections to common database APIs, provided by easy-to-use connection factories. When working with multiple databases, a Service Locator helps you creating those factories. It supports [PDO](http://de.php.net/manual/en/book.pdo.php), [mysqli](http://www.php.net/manual/en/book.mysqli.php) and [Aura.SQL v1.3](https://github.com/auraphp/Aura.Sql/tree/master).\n\n[![Build Status](https://travis-ci.org/tomkyle/Databases.png?branch=master)](https://travis-ci.org/tomkyle/Databases)\n[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/tomkyle/Databases/badges/quality-score.png?s=54034d47b7bf4a47315e94af685db4ecd5f61196)](https://scrutinizer-ci.com/g/tomkyle/Databases/)\n[![Coverage Status](https://coveralls.io/repos/tomkyle/Databases/badge.png?branch=master)](https://coveralls.io/r/tomkyle/Databases?branch=master)\n\n##In a Nutshell\n###Single Database\n1. Setup **DatabaseConfig** with associative array or StdClass\n2. Create **DatabaseProvider** with config object (Dependency Injection) \n3. **Grab your connection** for the database API you like\n\n[Show it already!](#getting-started-single-database)\n\n###Multiple Databases\n1. **Describe database** connections in two-dimensional array or StdClass\n2. Setup **DatabaseServiceLocator** with config object \n3. Get **DatabaseProvider** from ServiceLocator\n4. **Grab your connection** for the database API you like\n\n[Show it already!](#multiple-databases-using-service-locator)\n\n\n##Installation\n\nThis library has no dependencies except from Fabien Potencier's [Pimple](https://github.com/fabpot/Pimple) library. It is installable and autoloadable via Composer. During installation, Composer will suggest to install [Aura.SQL v1.3](http://github.com/auraphp/Aura.Sql/tree/1.3.0), if you have not already. Install from command line or `composer.json` file:\n\n#####Command line\n    \n    composer require tomykle/databases\n\n#####composer.json\n    \"require\": {\n        \"tomkyle/databases\": \"~1.0\"\n    }\n\n\n\n\n\n##Getting started: Single Database\n\n###Overview\nEach `DatabaseProvider` needs some info about the database in question, passed as parameter implementing the `DatabaseConfigInterface`. A ready-to-use implementation is the `DatabaseConfig`, which itself is configured either by an associative array or StdClass.\n\nNow that you have your `DatabaseConfig` ready, simply pass to new `DatabaseProvider` and grab the connection you like.\n\n###Example\n```php\n\u003c?php\nuse \\tomkyle\\Databases\\DatabaseConfig;\nuse \\tomkyle\\Databases\\DatabaseProvider;\n\n// 1a. Describe your database as array:\n$describe = array(\n  'host'     =\u003e \"localhost\",\n  'database' =\u003e \"database1\",\n  'user'     =\u003e \"root\",\n  'pass'     =\u003e \"secret\",\n  'charset'  =\u003e \"utf8\"\n);\n\n// 1b. Describe your database as StdClass:\n$describe = json_decode('{\n  \"host\":     \"localhost\",\n  \"database\": \"database1\"\n  # etc.\n}');\n\n// 2. Setup DatabaseConfig instance:\n$config = new DatabaseConfig( $describe );\n\n// 3. Create DatabaseProvider instance:\n$factory = new DatabaseProvider( $config );\n\n// 4. Grab Aura.SQL connection:\n$aura = $factory-\u003egetAuraSql();\n```\n\n###Configuration options\nIf one of these fields is empty or missing, `DatabaseConfig` will throw a `RuntimeException`:\n\n- **host:** The host name\n- **database:** The name of the database\n- **user** or **username:** the database user\n- **pass** or **password:** the database password\n\nOptional fields, with default values according to MySQL:\n\n- **charset:** the charset to use, defaults to `utf8`\n- **type:** the database type, defaults to `mysql`\n- **port:** the database port, defaults to `3306`\n\n\n###Retrieving connections\n\nEach `DatabaseProvider` instance provides and instantiates different kinds of Singleton-like database connections. You may grab your connection either by calling a Getter method or access it as array key (the Pimple way):\n\n####PDO Connections\n\n```php\n$pdo = $factory-\u003egetPdo();\n// or \n$pdo = $factory['pdo'];\n\necho get_class( $pdo );\n// \"PDO\"\n```\n\n####Aura.SQL Connections\n\n```php\naura = $factory-\u003egetAuraSql();\n// or \n$aura = $factory['aura.sql'];\n\necho get_class( $aura );\n// \"Aura\\Sql\\Connection\\Mysql\", for example\n\n// Common configuration afterwards\n$aura-\u003esetAttribute( \\PDO::ATTR_ERRMODE,             \\PDO::ERRMODE_EXCEPTION );\n$aura-\u003esetAttribute( \\PDO::ATTR_DEFAULT_FETCH_MODE,  \\PDO::FETCH_OBJ);\n```\n\n\n\n####mysqli Connections\n\n```php\n$mysqli = $factory-\u003egetMysqli();\n// or \n$mysqli = $factory['mysqli'];\n\necho get_class( $mysqli );\n// \"mysqli\"\n```\n\n\n\n\n\n\n\n\n\n\n\n\n\n##Multiple Databases: Using Service Locator\n\nAssume your project deals with a couple of different databases, with credentials and stuff in a JSON config file. First, describe each connection with config options (see [full list below](#configuration-options)), like this:\n\n#####Sample config file\n\n```json\n{\n  \"first_db\" : {\n    \"host\":     \"db_host\",\n    \"database\": \"db_name\",\n    \"user\":     \"db_user\",\n    \"pass\":     \"db_pass\"\n  },\n  \"second_db\" : {\n    \"host\":     \"other_host\",\n    \"database\": \"other_db\",\n    \"user\":     \"other_user\",\n    \"pass\":     \"other_pass\",\n    \"type\":     \"not_mysql\",\n    \"charset\":  \"utf8\"\n  }\n}\n```\n\n###Usage\n\n1. Parse config contents into a `StdClass` object\n2. Create a new instance of `DatabaseServiceLocator`,  \n   passing in your database descriptions\n3. Get your `DatabaseProvider` instance for your database\n4. Let factory create generic connection:\n\n```php\n\u003c?php\nuse \\tomkyle\\Databases\\DatabaseServiceLocator;\n\n$config = json_decode( file_get_contents( 'config.json' ));\n$databases = new DatabaseServiceLocator( $config );\n\n// 1. Get DatabaseProvider instance, Pimple-style:\n$first_factory = $databases['first_db'];\n\n// 2. Let factory create Aura.SQL connection:\n$first_aura = $first_factory-\u003egetAuraSql();\n```\n\n###Retrieving connections\nEach database passed in the `DatabaseServiceLocator` will be available like an array member. The database returned will be a Singleton-like instance of `DatabaseProvider`. \n\n```php\n$foo_factory = $databases['foo_db'];  \necho get_class( $foo_factory );\n// \"DatabaseProvider\"\n```\n\nSince both Service Locator and Factories are Pimple extensions, you can get your connection in one call as well:\n\n```php\n$databases = new DatabaseServiceLocator( $config );\n\n$first_pdo    = $databases['first_db']-\u003egetPdo();\n$first_mysqli = $databases['first_db']-\u003egetMysqli();\n$first_aura   = $databases['first_db']-\u003egetAuraSql();\n\n$second_pdo    = $databases['second_db']['pdo'];\n$second_mysqli = $databases['second_db']['mysqli'];\n$second_aura   = $databases['second_db']['aura.sql'];\n```\n\n\n\n\n##Best practice\nIf a class needs a special database connection, let's say PDO, here's how: \n\n1. Get your connection provider\n2. Let it create a PDO connection for you \n3. Inject the resulting PDO. \n\n…and the next class, relying on Aura.SQL dependencies:\n\n4. Take the very same connection provider instance (remember: Singleton!)\n5. Let it create a Aura.SQL connection for you\n6. Inject the resulting Aura.SQL Mysql Connection. \n\nThis way, when things go wrong, they do so outside your business classes (Inversion of Control).\n\nPaul M. Jones recently covers this topic in his recently published article [“What Application Layer Does A DI Container Belong In?”](http://paul-m-jones.com/archives/5914).\n\n\n##Questions and Answers\n\n\n###Wait, isn't this an Anti-Pattern?\n**Yes, if you use** the DatabaseServiceLocator as dependency inside your classes, injecting it in constructors or Setter methods, type-hinting against it or not. **No, if you use** it in your composition root or configuration environment.\n\n\n###How far are the connections configured?\nBeside from their charset, the connections “ex factory” are not configured specially. So if you like to change the default fetch mode or (think of `PDO::setAttribute`), you may want to configure it yourself. Remember, each connection is generic!\n\n###What about Aura.SQL v2 ?\nCurrently, DatabaseServiceLocator supports [Aura.SQL v1.3](http://github.com/auraphp/Aura.Sql/tree/1.3.0). With Aura v2 coming soon, Aura.SQL splits up into three modules *Aura.SQL v2  Aura.SQL_Query* and *Aura.SQL_Schema* – see Paul M. Jones' article [“A Peek At Aura v2 -- Aura.Sql and ExtendedPdo”](http://auraphp.com/blog/2013/10/21/aura-sql-v2-extended-pdo/). \n\nI will try to add v2 support as soon as v2 has become stable or standard, and I got used to it. Just in case you already are, you are invited to fork your own DatabaseServiceLocator :-)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomkyle%2Fdatabases","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomkyle%2Fdatabases","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomkyle%2Fdatabases/lists"}