{"id":43255873,"url":"https://github.com/nagyatka/pandabase","last_synced_at":"2026-02-01T13:33:03.094Z","repository":{"id":53538573,"uuid":"62339168","full_name":"nagyatka/pandabase","owner":"nagyatka","description":"PHP ORM","archived":false,"fork":false,"pushed_at":"2023-04-06T15:39:01.000Z","size":199,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-20T17:54:18.935Z","etag":null,"topics":["database","lightweight","mysql","orm","pandabase","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nagyatka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-30T20:07:09.000Z","updated_at":"2021-01-05T21:21:47.000Z","dependencies_parsed_at":"2022-08-23T13:50:56.115Z","dependency_job_id":null,"html_url":"https://github.com/nagyatka/pandabase","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/nagyatka/pandabase","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nagyatka%2Fpandabase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nagyatka%2Fpandabase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nagyatka%2Fpandabase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nagyatka%2Fpandabase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nagyatka","download_url":"https://codeload.github.com/nagyatka/pandabase/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nagyatka%2Fpandabase/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28979124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T12:13:08.691Z","status":"ssl_error","status_checked_at":"2026-02-01T12:13:08.356Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["database","lightweight","mysql","orm","pandabase","php"],"created_at":"2026-02-01T13:33:02.405Z","updated_at":"2026-02-01T13:33:03.082Z","avatar_url":"https://github.com/nagyatka.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PandaBase\n\n## Installation\n\n```bash\n$ composer require nagyatka/pandabase\n```\nWe recommend that use version above v0.20.0, because of significant API and performance changes.\n\n## How to use ConnectionManager\n### Get ConnectionManager instance\nYou can reach the ConnectionManager singleton instance globally via `getInstance()` method\n```php\n$connectionManager = ConnectionManager::getInstance();\n```\n### Add connection to manager object\nYou can easily set a new database connection in Pandabase.\n```php\n$connectionManager-\u003einitializeConnection([\n    \"name\"      =\u003e  \"test_connection\",  // Connection's name.\n    \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n    \"dbname\"    =\u003e  \"test_dbname\",      // Same as PDO parameter\n    \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n    \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n    \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n    \"attributes\"=\u003e  [\n        attributeName =\u003e value,\n        ...\n    ]                                   // Optional, PDO attributes\n]);\n```\n### Add more connection to manager object\nConnectionManager is able to handle more connection at time. The connections can be distinguished via the name parameter,\nfor example you can use `\"test_connection1\"` and `\"test_connection2\"` in the following example:\n```php\n$connectionManager-\u003einitializeConnections(\n    [\n        [\n            \"name\"      =\u003e  \"test_connection1\", // Connection's name.\n            \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n            \"dbname\"    =\u003e  \"test_dbname1\",     // Same as PDO parameter\n            \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n            \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n            \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n        ],\n        [\n            \"name\"      =\u003e  \"test_connection2\", // Connection's name.\n            \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n            \"dbname\"    =\u003e  \"test_dbname2\",     // Same as PDO parameter\n            \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n            \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n            \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n        ],\n\n    ]\n);\n```\n\n### Get connection\nThe `getConnection` method returns with the default connection if you leave the name parameter empty. The default connection\nwill be the firstly set connections.\n```php\n$connection = $connectionManager-\u003egetConnection();\n```\n\n### Get connection by name\n```php\n$connection = $connectionManager-\u003egetConnection(\"test_connection2\");\n```\n\n### Set the default connection by name\n```php\n// Set the 'test_connection2' Connection instance as the default\n$connectionManager-\u003esetDefault(\"test_connection2\");\n\n// Returns with the instance of 'test_connection2' if exists\n$connection = $connectionManager-\u003egetConnection();\n```\n\n### Execute queries using ConnectionManager\n```php\n\n// Fetch a result row as an associative array\n$queryResult = ConnectionManager::fetchAssoc(\"SELECT * FROM table1 WHERE table_id = :_id\", [\n    \"_id\" =\u003e 11\n]); \n\n// Fetch result from default connection\n$queryResult1 = ConnectionManager::fetchAll(\"SELECT * FROM table1\");\n\n// Fetch result from default connection with parameters\n$queryResult2 = ConnectionManager::fetchAll(\"SELECT * FROM table1 WHERE store_date \u003e :actual_date\",[\n    \"actual_date\" =\u003e date(\"Y-m-d H:i:s\")\n]);\n\n// Fetch result from specified connection (without parameters)\n$queryResult3 = ConnectionManager::fetchAll(\"SELECT * FROM table1\",[],\"test_connection2\");\n\n```\n\n\n# How to use Connection\n\nConnection is a PDO wrapper (all PDO function is callable) and provides a modified fetchAssoc and fetchAll methods for\nbetter usability. Although the ConnectionManager instance provides wrapper function for Connection instance's function\nso we recommend to use these wrapper function instead of calling them directly.\n\n### Get connection\n```php\n$connection = $connectionManager-\u003egetConnection();\n```\n\n### Fetch a result row as an associative array\n```php\n$result = $connection-\u003efetchAssoc(\"SELECT * FROM table1 WHERE id = :id\",[\"id\" =\u003e $id]);\n```\n\n### Returns with an array containing all of the result set rows as an associative array\n```php\n$result = $connection-\u003efetchAll(\"SELECT * FROM table1\",[]);\n```\n\n## Create classes based on database scheme\n\nYou can create classes based on tables of database. To achieve this, you have to only extend your classes from SimpleRecord or\nHistoryableRecord and register them to the specified connection.\n\n### SimpleRecord\n\n#### Implement a SimpleRecord class\n\nAssume that we have a MySQL table named as transactions and it has a primary key.\n\n```mysql\nCREATE TABLE `database_name`.`transactions` (\n\t`transaction_id` int(11) NOT NULL AUTO_INCREMENT,\n\t`transaction_value` int(11),\n\t`user_id` int(11),\n\t`store_date` datetime,\n\tPRIMARY KEY (`transaction_id`)\n) ENGINE=`InnoDB` COMMENT='';\n```\nImplement Transaction class:\n```php\nclass Transaction extends SimpleRecord {\n\n}\n```\nIn next step you have to add a Table object (this is a table descriptor class) to the specified Connection instance in\nthe following way when you initialize the connection: \n```php\n$connectionManager-\u003einitializeConnection([\n    \"name\"      =\u003e  \"test_connection\",  // Connection's name.\n    \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n    \"dbname\"    =\u003e  \"database_name\",    // Same as PDO parameter\n    \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n    \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n    \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n    \"attributes\"=\u003e  [\n        attributeName =\u003e value,\n        ...\n    ],                                  // Optional, PDO attributes\n    \"tables\"    =\u003e  [\n        Transaction::class  =\u003e new Table([\n            Table::TABLE_NAME =\u003e \"transactions\",\n            Table::TABLE_ID   =\u003e \"transaction_id\",\n        ]),\n        ...\n    ]\n]);\n```\nAnd that's all! Now you can create, update and delete records from the table:\n```php\n// Create a new empty record (if your table scheme allows it)\n$emptyRecord = new Transaction();\n// Create a new record with values\n$newRecord = new Transaction([\n            \"transaction_value\"     =\u003e  5000,\n            \"user_id\"               =\u003e  1234,\n            \"store_date\"            =\u003e  date('Y-m-d H:i:s')\n]);\n// To create new records in table you have to call ConnectionManager's persist function\nConnectionManager::persist($emptyRecord);\nConnectionManager::persist($newRecord);\n\n// An other option is to use persistAll function\nConnectionManager::persistAll([\n    $emptyRecord,\n    $newRecord\n]);\n\n// Now $emptyRecord and $newRecord have transaction_id attribute\necho $emptyRecord[\"transaction_id\"].\" \".$newRecord[\"transaction_id\"].\"\\n\";\n\n\n\n// Load record\n$transaction = new Transaction($transactionId);\necho $transation-\u003eget(\"store_date\").\": \".$transaction[\"transaction_value\"]; // You can use object as an array\n\n// Load multiple record from transaction table (get all transaction of an user)\n$transactions = ConnectionManager::getInstanceRecords(\n    Transaction::class,\n    \"SELECT * FROM transactions WHERE user_id = :user_id\",\n    [\n        \"user_id\"   =\u003e  1234\n    ]\n);\n\n\n\n// Update record\n$transaction = new Transaction($transactionId);\n$transation-\u003eset(\"transaction_value\",4900);\n$transation[\"store_date\"] = date('Y-m-d H:i:s'); //You can use object as an array\nConnectionManager::persist($transation);\n\n\n\n// Remove record\n$transaction = new Transaction($transactionId);\n$transation-\u003eremove();\n```\n\n### HistoryableRecord\n\nHistoryableRecord has the same features as SimpleRecord but it also storea the previous state of a record.\n\n#### Implement a HistoryableRecord class\n\nAssume that we have a MySQL table named as transactions and the table has the following columns (all of them required):\n* sequence_id (PRIMARY KEY)\n* id (record identifier, you can use it as ID in your code)\n* record_status (0|1 -\u003e inactive|active)\n* history_from (datetime)\n* history_to (datetime)\n\n```mysql\nCREATE TABLE `database_name`.`orders` (\n    `order_sequence_id` int(11) NOT NULL AUTO_INCREMENT,\n\t`order_id` int(11),\n\t`record_status` int(1),\n\t`history_from` datetime,\n\t`history_to` datetime,\n\t`order_status` int(11),\n\t`user_id` int(11),\n\t`store_date` datetime,\n\tPRIMARY KEY (`order_sequence_id`)\n) ENGINE=`InnoDB` COMMENT='';\n```\nImplement Order class:\n```php\nclass Order extends HistoryableRecord {\n    const Pending       = 0;\t\n    const Processing    = 1;\t\n    const Completed\t    = 2;\n    const Declined      = 3;\t\n    const Cancelled     = 4;\n    \n    /**\n     * Constructor\n     */\n    public function __construct($parameters) {\n        $parameters[\"order_status\"] = Order::Pending;\n        parent::__construct($parameters);\n    }\n    \n    ...\n}\n```\nIn next step you have to add a Table object (this is a table descriptor class) to the specified Connection instance in\nthe following way when you initialize the connection: \n```php\n$connectionManager-\u003einitializeConnection([\n    \"name\"      =\u003e  \"test_connection\",  // Connection's name.\n    \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n    \"dbname\"    =\u003e  \"database_name\",    // Same as PDO parameter\n    \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n    \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n    \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n    \"attributes\"=\u003e  [\n        attributeName =\u003e value,\n        ...\n    ],                                  // Optional, PDO attributes\n    \"tables\"    =\u003e  [\n        Order::class  =\u003e new Table([\n            Table::TABLE_NAME   =\u003e \"orders\",\n            Table::TABLE_ID     =\u003e \"order_id\",\n            Table::TABLE_SEQ_ID =\u003e \"order_sequence_id\"\n        ]),\n        ...\n    ]\n]);\n```\nNow you can use HistoryableRecord as a SimpleRecord, but you can get also historical information about the instance:\n```php\n    $order = new Order($order_id);\n    \n    // Get full history\n    $orderHistory = $order-\u003egetHistory();\n    \n    // You can also specify a date interval\n    $orderHistory = $order-\u003egetHistoryBetweenDates(\"2017-01-05\",\"2017-01-08\");\n```\n\n### Lazy attributes\n\nSometimes you have to store foreign keys in your table to represent connection between different objects. Without lazy\nattribute load you can load the objects this way:\n```php\n    $transaction = new Transaction($transactionId);\n    $order = new Order($transaction-\u003eget(\"order_id\")); // We suppose that a transaction table also stores a valid order_id\n```\nOr if you want to provide a class method:\n```php\n    class Transaction extends SimpleRecord {\n        // ...\n        \n        /** @var Order */\n        private $order;\n        \n        // ...\n        \n        /** @return Order */\n        public function getOrder() {\n            if($this-\u003eorder == null) {\n                $this-\u003eorder = new Order($this-\u003eget(\"order_id\"));\n            }\n            return $this-\u003eorder;\n        }\n    }\n```\nInstead of this, you can use LazyAttribute to implement this kind of connection on fast and easily way.\n\n\nFirst you have to extend your table description. In our example we'd like to store an 'order_id' for a transaction record\nand want to reach the appropriate Order instance via 'order' key:\n```php\n$connectionManager-\u003einitializeConnection([\n    \"name\"      =\u003e  \"test_connection\",  // Connection's name.\n    \"driver\"    =\u003e  \"mysql\",            // Same as PDO parameter\n    \"dbname\"    =\u003e  \"database_name\",    // Same as PDO parameter\n    \"host\"      =\u003e  \"127.0.0.1\",        // Same as PDO parameter\n    \"user\"      =\u003e  \"root\",             // Same as PDO parameter\n    \"password\"  =\u003e  \"\"                  // Same as PDO parameter\n    \"attributes\"=\u003e  [\n        attributeName =\u003e value,\n        ...\n    ],                                  // Optional, PDO attributes\n    \"tables\"    =\u003e  [\n        Order::class  =\u003e new Table([\n            Table::TABLE_NAME   =\u003e \"orders\",\n            Table::TABLE_ID     =\u003e \"order_id\",\n            Table::TABLE_SEQ_ID =\u003e \"order_sequence_id\"\n        ]),\n        Transaction::class  =\u003e new Table([\n            Table::TABLE_NAME       =\u003e \"transactions\",\n            Table::TABLE_ID         =\u003e \"transaction_id\",\n            Table::LAZY_ATTRIBUTES  =\u003e [\n                \"order\" =\u003e new LazyAttribute(\"order_id\",Order::class)\n            ]\n        ]),\n        ...\n    ]\n]);\n```\n(We supposed that you extended the mysql table declaration too with the new 'order_id' column.)\n\nNow you can use a Transaction instance in the following way:\n\n```php\n// Load Transaction instance from db\n$transaction = new Transaction($transactionId);\n\necho $transation-\u003eget(\"store_date\").\": \".$transaction[\"transaction_value\"]; // You can use object as an array\n\n/** @var Order $transactionOrder */\n$transactionOrder = $transaction[\"order\"]; // Return with an Order instance\n$transactionOrderHistory = $transactionOrder-\u003egetHistory();\n```\n\n\n\n\n\n\n####### TODO: AccessManagement\n\n\n## License\nPandaBase is licensed under the Apache 2.0 License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnagyatka%2Fpandabase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnagyatka%2Fpandabase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnagyatka%2Fpandabase/lists"}