{"id":15729147,"url":"https://github.com/voku/simple-active-record","last_synced_at":"2025-05-12T14:03:18.457Z","repository":{"id":40695634,"uuid":"162640849","full_name":"voku/simple-active-record","owner":"voku","description":":ring: Active Record Pattern via PHP","archived":false,"fork":false,"pushed_at":"2025-02-08T03:49:05.000Z","size":63,"stargazers_count":5,"open_issues_count":6,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-08T12:01:48.922Z","etag":null,"topics":["active-record","activerecord","database","hacktoberfest","mysql","php","php7","sql"],"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/voku.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-12-20T23:12:08.000Z","updated_at":"2023-09-27T00:00:34.000Z","dependencies_parsed_at":"2024-04-15T09:05:34.790Z","dependency_job_id":"bcaf1a7c-5815-4c2e-939c-c503fa538bf2","html_url":"https://github.com/voku/simple-active-record","commit_stats":{"total_commits":31,"total_committers":5,"mean_commits":6.2,"dds":"0.22580645161290325","last_synced_commit":"b052cb27fadecf5e79028f0b4039b6bcb8e67bed"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voku%2Fsimple-active-record","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voku%2Fsimple-active-record/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voku%2Fsimple-active-record/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voku%2Fsimple-active-record/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voku","download_url":"https://codeload.github.com/voku/simple-active-record/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253754091,"owners_count":21958838,"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":["active-record","activerecord","database","hacktoberfest","mysql","php","php7","sql"],"created_at":"2024-10-03T23:20:26.260Z","updated_at":"2025-05-12T14:03:18.367Z","avatar_url":"https://github.com/voku.png","language":"PHP","readme":"[![Build Status](https://travis-ci.com/voku/simple-active-record.svg?branch=master)](https://travis-ci.com/voku/simple-active-record)\n[![Coverage Status](https://coveralls.io/repos/github/voku/simple-active-record/badge.svg?branch=master)](https://coveralls.io/github/voku/simple-active-record?branch=master)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db0b681fd4bf434eaceaa5213698ea3e)](https://www.codacy.com/app/voku/simple-active-record)\n[![Latest Stable Version](https://poser.pugx.org/voku/simple-active-record/v/stable)](https://packagist.org/packages/voku/simple-active-record) \n[![Total Downloads](https://poser.pugx.org/voku/simple-active-record/downloads)](https://packagist.org/packages/voku/simple-active-record)\n[![License](https://poser.pugx.org/voku/simple-active-record/license)](https://packagist.org/packages/voku/simple-active-record)\n[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.me/moelleken)\n[![Donate to this project using Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://www.patreon.com/voku)\n\n# :ring: Simple Active Record\n\nThis is a simple Active Record Pattern compatible with PHP 7+ that provides a simple \nand _secure_ interaction with your database using :gem: [\"Simple MySQLi\"](https://github.com/voku/simple-mysqli/) at \nits core. This is perfect for small scale applications such as cron jobs, \nfacebook canvas campaigns or micro frameworks or sites. \n\n\n### Get \"Simple Active Record\"\n\nYou can download it from here, or require it using [composer](https://packagist.org/packages/voku/simple-mysqli).\n```json\n  {\n      \"require\": {\n        \"voku/simple-active-record\": \"1.*\"\n      }\n  }\n```\n\n### Install via \"composer require\"\n```shell\n  composer require voku/simple-active-record\n```\n\n* [Starting the driver](#starting-the-driver)\n* [Multiton \u0026\u0026 Singleton](#multiton--singleton)\n* [Doctrine/DBAL as parent driver](#doctrinedbal-as-parent-driver)\n* [Using the \"ActiveRecord\"-Class (OOP database-access)](#using-the-activerecord-class-oop-database-access)\n    * [setDb(DB $db)](#setdbdb-db)\n    * [insert() : bool|int](#insert--boolint)\n    * [fetch(integer $id = null) : bool|\\ActiveRecord](#fetchinteger--id--null--boolactiverecord)\n    * [fetchAll() : $this[]](#fetchall--this)\n    * [update() : bool|int](#update--boolint)\n    * [delete() : bool](#update--boolint)\n  * [Active Record | SQL part functions](#active-record--sql-part-functions)\n    * [select()](#select)\n    * [from()](#from)\n    * [join()](#join)\n    * [where()](#where)\n    * [group()](#group)\n    * [order()](#order)\n    * [limit()](#limit)\n  * [Active Record | WHERE conditions](#active-record--where-conditions)\n    * [equal()/eq()](#equaleq)\n    * [notEqual()/ne()](#notequalne)\n    * [greaterThan()/gt()](#greaterthangt)\n    * [lessThan()/lt()](#lessthanlt)\n    * [greaterThanOrEqual()/ge()/gte()](#greaterthanorequalgegte)\n    * [lessThanOrEqual()/le()/lte()](#lessthanorequallelte)\n    * [like()](#like)\n    * [in()](#in)\n    * [notIn()](#notin)\n    * [isNull()](#isnull)\n    * [isNotNull()/notNull()](#isnotnullnotnull)\n  * [Active Record | Demo](#active-record---demo)\n* [Logging and Errors](#logging-and-errors)\n* [Changelog](#changelog)\n\n\n### Starting the driver\n```php\n  use voku\\db\\DB;\n\n  require_once 'composer/autoload.php';\n\n  $db = DB::getInstance('yourDbHost', 'yourDbUser', 'yourDbPassword', 'yourDbName');\n  \n  // example\n  // $db = DB::getInstance('localhost', 'root', '', 'test');\n```\n\n### Multiton \u0026\u0026 Singleton\n\nYou can use ```DB::getInstance()``` without any parameters and you will get your (as \"singleton\") first initialized connection. Or you can change the parameter and you will create an new \"multiton\"-instance which works like an singleton, but you need to use the same parameters again, otherwise (without the same parameter) you will get an new instance. \n\n### Doctrine/DBAL as parent driver\n```php\n  use voku\\db\\DB;\n\n  require_once 'composer/autoload.php';\n  \n  $connectionParams = [\n      'dbname'   =\u003e 'yourDbName',\n      'user'     =\u003e 'yourDbUser',\n      'password' =\u003e 'yourDbPassword',\n      'host'     =\u003e 'yourDbHost',\n      'driver'   =\u003e 'mysqli', // 'pdo_mysql' || 'mysqli'\n      'charset'  =\u003e 'utf8mb4',\n  ];\n  $config = new \\Doctrine\\DBAL\\Configuration();\n  $doctrineConnection = \\Doctrine\\DBAL\\DriverManager::getConnection(\n      $connectionParams,\n      $config\n  );\n  $doctrineConnection-\u003econnect();\n\n  $db = DB::getInstanceDoctrineHelper($doctrineConnection);\n```\n\n### Using the \"ActiveRecord\"-Class (OOP database-access)\n\nA simple implement of active record pattern via Arrayy.\n\n#### setDb(DB $db) \nset the DB connection.\n\n```php\n  $db = DB::getInstance('YOUR_MYSQL_SERVER', 'YOUR_MYSQL_USER', 'YOUR_MYSQL_PW', 'YOUR_DATABASE');\n  ActiveRecord::setDb($db);\n```\n\n#### insert() : bool|int\nThis function can build insert SQL queries and can insert the current record into database.\nIf insert was successful, it will return the new id, otherwise it will return false or true (if there are no dirty data).\n\n```php\n  $user = new User();\n  $user-\u003ename = 'demo';\n  $user-\u003epassword = password_hash('demo', PASSWORD_BCRYPT, [\"cost\" =\u003e 15]);\n  $user_id = $user-\u003einsert();\n  \n  var_dump($user_id); // the new id \n  var_dump($user-\u003eid); // also the new id \n  var_dump($user-\u003egetPrimaryKey()); // also the new id \n```\n\n#### fetch(integer  $id = null) : bool|\\ActiveRecord\nThis function can fetch one record and assign in to current object.\nIf you call this function with the $id parameter, it will fetch records by using the current primary-key-name.\n\n```php\n  $user = new User();\n\n  $user-\u003enotnull('id')-\u003eorderBy('id desc')-\u003efetch();\n  \n  // OR //\n  \n  $user-\u003efetch(1);\n  \n  // OR //\n  \n  $user-\u003efetchById(1); // thows \"FetchingException\" if the ID did not exists\n  \n  // OR //\n  \n  $user-\u003efetchByIdIfExists(1); // return NULL if the ID did not exists\n  \n    \n  // OR //\n  \n  $user-\u003efetchByHashId('fsfsdwldasdar'); // thows \"FetchingException\" if the ID did not exists\n  \n  // OR //\n  \n  $user-\u003efetchByHashIdIfExists('fsfsdwldasdar'); // return NULL if the ID did not exists\n  \n  var_dump($user-\u003eid); // (int) 1\n  var_dump($user-\u003egetPrimaryKey()); // (int) 1\n```\n\n#### fetchAll() : $this[]\nThis function can fetch all records in the database and will return an array of ActiveRecord objects.\n\n```php\n  $user = new User();\n\n  $users = $user-\u003efetchAll();\n  \n  // OR //\n  \n  $users = $user-\u003efetchByIds([1]);\n  \n  // OR //\n  \n  $users = $user-\u003efetchByIdsPrimaryKeyAsArrayIndex([1]);\n    \n  var_dump($users[0]-\u003eid) // (int) 1\n  var_dump($users[0]-\u003egetPrimaryKey()); // (int) 1\n```\n\n#### update() : bool|int\nThis function can build update SQL queries and can update the current record in database, just write the dirty data into database.\nIf update was successful, it will return the affected rows as int, otherwise it will return false or true (if there are no dirty data).\n\n```php\n  $user = new User();\n  $user-\u003enotnull('id')-\u003eorderBy('id desc')-\u003efetch();\n  $user-\u003eemail = 'test@example.com';\n  $user-\u003eupdate();\n```\n\n#### delete() : bool\nThis function can delete the current record in the database. \n\n### Active Record | SQL part functions\n\n#### select()\nThis function can set the select columns.\n\n```php\n  $user = new User();\n  $user-\u003eselect('id', 'name')-\u003efetch();\n```\n\n#### from()\nThis function can set the table to fetch record from.\n\n```php\n  $user = new User();\n  $user-\u003eselect('id', 'name')-\u003efrom('user')-\u003efetch();\n```\n\n#### join()\nThis function can set the table to fetch record from.\n\n```php\n  $user = new User();\n  $user-\u003ejoin('contact', 'contact.user_id = user.id')-\u003efetch();\n```\n\n#### where()\nThis function can set where conditions.\n\n```php\n  $user = new User();\n  $user-\u003ewhere('id=1 AND name=\"demo\"')-\u003efetch();\n```\n\n#### groupBy()\nThis function can set the \"group by\" conditions.\n\n```php\n  $user = new User();\n  $user-\u003eselect('count(1) as count')-\u003egroupBy('name')-\u003efetchAll();\n```\n\n#### orderBy()\nThis function can set the \"order by\" conditions.\n\n```php\n  $user = new User();\n  $user-\u003eorderBy('name DESC')-\u003efetch();\n```\n\n#### limit()\nThis function can set the \"limit\" conditions.\n\n```php\n  $user = new User();\n  $user-\u003eorderBy('name DESC')-\u003elimit(0, 1)-\u003efetch();\n```\n\n### Active Record | WHERE conditions\n\n#### equal()/eq()\n\n```php\n  $user = new User();\n  $user-\u003eeq('id', 1)-\u003efetch();\n```\n\n#### notEqual()/ne()\n\n```php\n  $user = new User();\n  $user-\u003ene('id', 1)-\u003efetch();\n```\n\n#### greaterThan()/gt()\n\n```php\n  $user = new User();\n  $user-\u003egt('id', 1)-\u003efetch();\n```\n\n#### lessThan()/lt()\n\n```php\n  $user = new User();\n  $user-\u003elt('id', 1)-\u003efetch();\n```\n\n#### greaterThanOrEqual()/ge()/gte()\n\n```php\n  $user = new User();\n  $user-\u003ege('id', 1)-\u003efetch();\n```\n\n#### lessThanOrEqual()/le()/lte()\n\n```php\n  $user = new User();\n  $user-\u003ele('id', 1)-\u003efetch();\n```\n\n#### like()\n\n```php\n  $user = new User();\n  $user-\u003elike('name', 'de')-\u003efetch();\n```\n\n#### in()\n\n```php\n  $user = new User();\n  $user-\u003ein('id', [1, 2])-\u003efetch();\n```\n\n#### notIn()\n\n```php\n  $user = new User();\n  $user-\u003enotin('id', [1, 3])-\u003efetch();\n```\n\n#### isNull()\n\n```php\n  $user = new User();\n  $user-\u003eisnull('id')-\u003efetch();\n```\n\n#### isNotNull()/notNull()\n\n```php\n  $user = new User();\n  $user-\u003eisNotNull('id')-\u003efetch();\n```\n\n\n### Active Record | Demo\n\n#### Include \u0026\u0026 Init\n\n```php\nuse voku\\db\\DB;\nuse voku\\db\\ActiveRecord;\n\nrequire_once 'composer/autoload.php';\n\n$db = DB::getInstance('YOUR_MYSQL_SERVER', 'YOUR_MYSQL_USER', 'YOUR_MYSQL_PW', 'YOUR_DATABASE');\nActiveRecord::setDb($db);\n```\n\n#### Define Class\n```php\nnamespace demo;\n\nuse voku\\db\\ActiveRecord;\n\n/**\n * @property int       $id\n * @property string    $name\n * @property string    $password\n * @property Contact[] $contacts\n * @property Contact   $contacts_with_backref\n * @property Contact   $contact\n */\nclass User extends ActiveRecord {\n  public $table = 'user';\n\n  public $primaryKey = 'id';\n  \n  protected function init()\n  {\n      $this-\u003eaddRelation(\n          'contacts',\n          self::HAS_MANY,\n          FoobarContact::class,\n          'user_id'\n      );\n\n      $this-\u003eaddRelation(\n          'contacts_with_backref',\n          self::HAS_MANY,\n          FoobarContact::class,\n          'user_id',\n          null,\n          'user'\n      );\n\n      $this-\u003eaddRelation(\n        'contact',\n          self::HAS_ONE,\n          FoobarContact::class,\n          'user_id',\n          [\n              self::SQL_WHERE =\u003e '1 = 1',\n              self::SQL_ORDER =\u003e 'id desc',\n          ]\n      );\n  }\n}\n\n/**\n * @property int    $id\n * @property int    $user_id\n * @property string $email\n * @property string $address\n * @property User   $user_with_backref\n * @property User   $user\n */\nclass Contact extends ActiveRecord {\n  public $table = 'contact';\n\n  public $primaryKey = 'id';\n  \n  protected function init()\n  {\n      $this-\u003eaddRelation(\n          'user_with_backref',\n          self::BELONGS_TO,\n          FoobarUser::class,\n          'user_id',\n          null,\n          'contact'\n      );\n\n      $this-\u003eaddRelation(\n          'user',\n          self::BELONGS_TO,\n          FoobarUser::class,\n          'user_id'\n      );\n  }\n}\n```\n\n#### Init data (for testing - use migrations for this step, please)\n```sql\nCREATE TABLE IF NOT EXISTS user (\n  id INTEGER PRIMARY KEY, \n  name TEXT, \n  password TEXT \n);\n\nCREATE TABLE IF NOT EXISTS contact (\n  id INTEGER PRIMARY KEY, \n  user_id INTEGER, \n  email TEXT,\n  address TEXT\n);\n```\n\n#### Insert one User into database.\n```php\nuse demo\\User;\n\n$user = new User();\n$user-\u003ename = 'demo';\n$user-\u003epassword = password_hash('demo', PASSWORD_BCRYPT, [\"cost\" =\u003e 15]);\n$user_id = $user-\u003einsert();\n\nvar_dump($user_id); // the new id \nvar_dump($user-\u003eid); // also the new id \nvar_dump($user-\u003egetPrimaryKey()); // also the new id \n```\n\n#### Insert one Contact belongs the current user.\n```php\nuse demo\\Contact;\n\n$contact = new Contact();\n$contact-\u003eaddress = 'test';\n$contact-\u003eemail = 'test1234456@domain.com';\n$contact-\u003euser_id = $user-\u003eid;\n\nvar_dump($contact-\u003einsert()); // the new id \nvar_dump($contact-\u003eid); // also the new id \nvar_dump($contact-\u003egetPrimaryKey()); // also the new id \n```\n\n#### Example to using relations \n```php\nuse demo\\User;\nuse demo\\Contact;\n\n$user = new User();\n\n// fetch one user\nvar_dump($user-\u003enotnull('id')-\u003eorderBy('id desc')-\u003efetch());\n\necho \"\\nContact of User # {$user-\u003eid}\\n\";\n// get contacts by using relation:\n//   'contacts' =\u003e [self::HAS_MANY, 'demo\\Contact', 'user_id'],\nvar_dump($user-\u003econtacts);\n\n$contact = new Contact();\n\n// fetch one contact\nvar_dump($contact-\u003efetch());\n\n// get user by using relation:\n//    'user' =\u003e [self::BELONGS_TO, 'demo\\User', 'user_id'],\nvar_dump($contact-\u003euser);\n```\n\n### Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n### Support\n\nFor support and donations please visit [Github](https://github.com/voku/simple-active-record/) | [Issues](https://github.com/voku/simple-active-record/issues) | [PayPal](https://paypal.me/moelleken) | [Patreon](https://www.patreon.com/voku).\n\nFor status updates and release announcements please visit [Releases](https://github.com/voku/simple-active-record/releases) | [Twitter](https://twitter.com/suckup_de) | [Patreon](https://www.patreon.com/voku/posts).\n\nFor professional support please contact [me](https://about.me/voku).\n\n### Thanks\n\n- Thanks to [GitHub](https://github.com) (Microsoft) for hosting the code and a good infrastructure including Issues-Managment, etc.\n- Thanks to [IntelliJ](https://www.jetbrains.com) as they make the best IDEs for PHP and they gave me an open source license for PhpStorm!\n- Thanks to [Travis CI](https://travis-ci.com/) for being the most awesome, easiest continous integration tool out there!\n- Thanks to [StyleCI](https://styleci.io/) for the simple but powerfull code style check.\n- Thanks to [PHPStan](https://github.com/phpstan/phpstan) \u0026\u0026 [Psalm](https://github.com/vimeo/psalm) for relly great Static analysis tools and for discover bugs in the code!\n","funding_links":["https://www.paypal.me/moelleken","https://www.patreon.com/voku","https://paypal.me/moelleken","https://www.patreon.com/voku/posts"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoku%2Fsimple-active-record","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoku%2Fsimple-active-record","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoku%2Fsimple-active-record/lists"}