{"id":18407529,"url":"https://github.com/simplecomplex/php-database","last_synced_at":"2025-04-12T21:14:16.436Z","repository":{"id":57051270,"uuid":"130175132","full_name":"simplecomplex/php-database","owner":"simplecomplex","description":"Database abstraction for transparent MariaDB (MySQL), MS SQL interaction","archived":false,"fork":false,"pushed_at":"2020-07-14T13:45:41.000Z","size":644,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T21:14:13.315Z","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/simplecomplex.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.txt","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":"2018-04-19T07:23:10.000Z","updated_at":"2020-07-08T08:59:54.000Z","dependencies_parsed_at":"2022-08-24T03:40:48.499Z","dependency_job_id":null,"html_url":"https://github.com/simplecomplex/php-database","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplecomplex%2Fphp-database","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplecomplex%2Fphp-database/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplecomplex%2Fphp-database/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simplecomplex%2Fphp-database/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simplecomplex","download_url":"https://codeload.github.com/simplecomplex/php-database/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631682,"owners_count":21136562,"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-06T03:14:23.954Z","updated_at":"2025-04-12T21:14:16.412Z","avatar_url":"https://github.com/simplecomplex.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# (PHP) Database #\n\n- [Database engine specifics](#database-engine-specifics)\n- [Examples - MariaDB/MySQL](#mariadb-mysql)\n- [Examples - MS SQL](#ms-sql)\n- [Requirements](#requirements)\n\n## Scope ##\n\nCompact cross-engine relational database abstraction which handles common engine-specific peculiarities.\n\n## Features ##\n\n- uniform classes and methods across database engines\n- _client_ - _query_ - _result_ architecture\n- chainable methods\n- a database broker to keep track of all created clients\n- extensive error handling/logging and defensive code style\n\n### Client ###\n- auto-reconnects, when reasonable\n- safe transaction handling\n- all connection options supported\n\n### Query ###\n- auto-detects parameter types when no type string (i|d|s|b) given\n- ?-parameter substitution in non-prepared statements\n\n### Result ###\n- affected rows, insert ID, number of rows, number of columns\n- fetch array/object, fetch all rows\n- moving to next set/row\n\n### MariaDB/MySQL features ###\n- multiple selecting queries, append query\n- result mode _use_; _store_ only for non-prepared statement\n- number of rows not supported for prepared statement (because _use_)\n\n### MS SQL features ###\n- automated typed arguments handling (SQLSRV_PARAM_IN etc.)\n- automated insert ID retrieval\n- result mode (SQLSRV_CURSOR_FORWARD etc.) defense against wrong use\n\n## Database engine specifics ##\n\n### MariaDB/MySQL (PHP MySQLi/mysqlnd) ###\n\nA MariaDB/MySQL **multi-query** is an SQL string containing more queries delimited by semicolon.  \nEvery query may be a SELECT (or likewise) producing a result set.\n\nPHP's MySQLi extension only offers native ?-parameter substitution for prepared statements,\nhowever the **``` MariaDb::parameters() ```** method mends that (_somewhat_); for simple statements.  \nStill, **go for prepared statements if security is the major concern**.\n\nThe MySQLi extension encompasses around 100 functions/methods/properties.\nFairly confusing; this abstraction only utilizes a dozen or so of them.\n\n### MS SQL (PHP Sqlsrv) ###\n\nPHP's Sqlsrv offers native ?-parameter substitution for simple statements as well as prepared statements.\n\nThere's no MS SQL **result mode** which supports (INSERT) affected-rows as well as (SELECT) num-rows.  \nSo care should be taken to use 'forward' when inserting and 'static' or 'keyset' when selecting;  \nuse **``` MsSqlClient::query() ```** option ``` (string) result_mode ```.\n\nMS SQL/Sqlsrv has no direct means for getting insert ID, but supports likewise via a 'magic' query\nappended to an INSERT statement.  \n**``` MsSqlQuery ```**+**``` MsSqlResult ```** handles the issue transparently when **``` MsSqlClient::query() ```** receives the option ``` (bool) insert_id ```.\n\nThe Sqlsrv extension is a well-made tight no-nonsense API consisting of 20-odd functions.\n\n## Examples ##\n\n### MariaDB/MySQL ###\n\n```php\n// Get or create client via the broker -----------------------------------------\n/** @var \\Psr\\Container\\ContainerInterface $container */\n$container = Dependency::container();\n/** @var \\SimpleComplex\\Database\\DatabaseBroker $db_broker */\n$db_broker = $container-\u003eget('database-broker');\n/** @var \\SimpleComplex\\Database\\MariaDbClient $client */\n$client = $db_broker-\u003egetClient(\n    'some-client',\n    'mariadb',\n    [\n        'host' =\u003e 'localhost',\n        'database' =\u003e 'some_database',\n        'user' =\u003e 'some-user',\n        'pass' =\u003e '∙∙∙∙∙∙∙∙',\n    ]\n);\n\n// Or create client directly ---------------------------------------------------\nuse SimpleComplex\\Database\\MariaDbClient;\n$client = new MariaDbClient(\n    'some-client',\n    [\n        'host' =\u003e 'localhost',\n        'database' =\u003e 'some_database',\n        'user' =\u003e 'some-user',\n        'pass' =\u003e '∙∙∙∙∙∙∙∙',\n    ]\n);\n\n// Insert two rows, using a prepared statement ---------------------------------\n$arguments = [\n    'lastName' =\u003e 'Doe',\n    'firstName' =\u003e 'Jane',\n    'birthday' =\u003e '1970-01-01',\n];\n/** @var \\SimpleComplex\\Database\\MariaDbQuery $query */\n$query = $client-\u003equery('INSERT INTO person (lastName, firstName, birthday) VALUES (?, ?, ?)')\n    -\u003eprepare('sss', $arguments)\n    // Insert first row.\n    -\u003eexecute();\n$arguments['firstName'] = 'John';\n// Insert second row.\n/** @var \\SimpleComplex\\Database\\MariaDbResult $result */\n$result = $query-\u003eexecute();\n$affected_rows = $result-\u003eaffectedRows();\n$insert_id = $result-\u003einsertId();\n\n// Get a row, using a simple statement -----------------------------------------\n$somebody = $client-\u003equery('SELECT * FROM person WHERE personId \u003e ? AND personId \u003c ?')\n    -\u003eparameters('ii', [1, 3])\n    -\u003eexecute()\n    -\u003efetchArray();\n\n// Get all rows, using a simple statement, and list them by 'personId' column --\n$everybody = $client-\u003equery('SELECT * FROM person')\n    -\u003eexecute()\n    -\u003efetchArrayAll(DbResult::FETCH_ASSOC, 'personId');\n```\n\n### MS SQL ###\n\n```php\n// Create client via the broker ------------------------------------------------\n/** @var \\SimpleComplex\\Database\\MsSqlClient $client */\n$client = Dependency::container()\n    -\u003eget('database-broker')\n    -\u003egetClient(\n        'some-client',\n        'mssql',\n        [\n            'host' =\u003e 'localhost',\n            'database' =\u003e 'some_database',\n            'user' =\u003e 'some-user',\n            'pass' =\u003e '∙∙∙∙∙∙∙∙',\n        ]\n    );\n\n// Insert two rows, using a prepared statement\n// and arguments that aren't declared as sqlsrv typed arrays -------------------\n$arguments = [\n    'lastName' =\u003e 'Doe',\n    'firstName' =\u003e 'Jane',\n    'birthday' =\u003e '1970-01-01',\n];\n/** @var \\SimpleComplex\\Database\\MsSqlQuery $query */\n$query = $client-\u003equery('INSERT INTO person (lastName, firstName, birthday) VALUES (?, ?, ?)', [\n        // SQLSRV_CURSOR_FORWARD to get affected rows.\n        'result_mode' =\u003e 'forward',\n        // For MsSqlResult::insertId().\n        'insert_id' =\u003e true,\n    ])\n    -\u003eprepare('sss', $arguments)\n    // Insert first row.\n    -\u003eexecute();\n$arguments['firstName'] = 'John';\n// Insert second row.\n/** @var \\SimpleComplex\\Database\\MsSqlResult $result */\n$result = $query-\u003eexecute();\n$affected_rows = $result-\u003eaffectedRows();\n$insert_id = $result-\u003einsertId();\n\n// Insert two rows, using a prepared statement\n// and types empty (guess type argument's actual type)\n// and arguments partially declared as sqlsrv typed arrays ---------------------\n$arguments = [\n    [\n        'Doe',\n        SQLSRV_PARAM_IN,\n        null,\n        SQLSRV_SQLTYPE_VARCHAR('max')\n    ],\n    [\n        'Jane',\n    ],\n    '1970-01-01',\n];\n$query = $client-\u003equery('INSERT INTO person (lastName, firstName, birthday) VALUES (?, ?, ?)')\n    -\u003eprepare('', $arguments)\n    // Insert first row.\n    -\u003eexecute();\n// Insert second row.\n$arguments[1][0] = 'John';\n$query-\u003eexecute();\n\n// Get a row, using a simple statement -----------------------------------------\n$somebody = $client-\u003equery('SELECT * FROM person WHERE personId \u003e ? AND personId \u003c ?')\n    -\u003eparameters('ii', [1, 3])\n    -\u003eexecute()\n    -\u003efetchArray();\n\n// Get all rows, using a simple statement, and list them by 'personId' column --\n$everybody = $client-\u003equery('SELECT * FROM person')\n    -\u003eexecute()\n    -\u003efetchArrayAll(DbResult::FETCH_ASSOC, 'personId');\n```\n\n## Requirements ##\n\n- PHP \u003e=7.0\n- [PSR-3 Log](https://github.com/php-fig/log)\n- [SimpleComplex Utils](https://github.com/simplecomplex/php-utils)\n- [SimpleComplex Validate](https://github.com/simplecomplex/php-validate)\n\nMariaDB equires the [mysqlnd driver](https://dev.mysql.com/downloads/connector/php-mysqlnd) (PHP default since v. 5.4),\nor better.\n\n### Suggestions ###\n\n- PHP MySQLi extension, if using MariaDB/MySQL database\n- PHP (PECL) Sqlsrv extension, if using MS SQL database\n- [SimpleComplex Inspect](https://github.com/simplecomplex/inspect) Great for logging; better variable dumps and traces.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimplecomplex%2Fphp-database","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimplecomplex%2Fphp-database","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimplecomplex%2Fphp-database/lists"}