{"id":21023506,"url":"https://github.com/jahidulpabelislam/orm","last_synced_at":"2026-02-19T01:18:29.826Z","repository":{"id":57002078,"uuid":"235672789","full_name":"jahidulpabelislam/orm","owner":"jahidulpabelislam","description":"Simple \u0026 lightweight ORM for PHP.","archived":false,"fork":false,"pushed_at":"2026-02-15T19:44:01.000Z","size":190,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"2.x","last_synced_at":"2026-02-15T19:51:09.289Z","etag":null,"topics":["database","entity","model","orm","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jahidulpabelislam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-01-22T21:40:36.000Z","updated_at":"2026-01-16T00:10:24.000Z","dependencies_parsed_at":"2024-03-28T22:22:41.093Z","dependency_job_id":"f2b9edf9-7b60-4b1b-949c-0143cca41abf","html_url":"https://github.com/jahidulpabelislam/orm","commit_stats":{"total_commits":41,"total_committers":2,"mean_commits":20.5,"dds":"0.24390243902439024","last_synced_commit":"88918dea6c0b4d1fa5bd489996845a39931eaf3c"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/jahidulpabelislam/orm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidulpabelislam%2Form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidulpabelislam%2Form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidulpabelislam%2Form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidulpabelislam%2Form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jahidulpabelislam","download_url":"https://codeload.github.com/jahidulpabelislam/orm/tar.gz/refs/heads/2.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidulpabelislam%2Form/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29600744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T00:59:38.239Z","status":"ssl_error","status_checked_at":"2026-02-19T00:59:36.936Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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","entity","model","orm","php"],"created_at":"2024-11-19T11:18:27.714Z","updated_at":"2026-02-19T01:18:29.814Z","avatar_url":"https://github.com/jahidulpabelislam.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ORM\n\n[![CodeFactor](https://www.codefactor.io/repository/github/jahidulpabelislam/orm/badge)](https://www.codefactor.io/repository/github/jahidulpabelislam/orm)\n[![Latest Stable Version](https://poser.pugx.org/jpi/orm/v/stable)](https://packagist.org/packages/jpi/orm)\n[![Total Downloads](https://poser.pugx.org/jpi/orm/downloads)](https://packagist.org/packages/jpi/orm)\n[![Latest Unstable Version](https://poser.pugx.org/jpi/orm/v/unstable)](https://packagist.org/packages/jpi/orm)\n[![License](https://poser.pugx.org/jpi/orm/license)](https://packagist.org/packages/jpi/orm)\n![GitHub last commit (branch)](https://img.shields.io/github/last-commit/jahidulpabelislam/orm/2.x.svg?label=last%20activity)\n\nA super simple \u0026 lightweight ORM following the active record pattern.\n\nThis has been kept very simple stupid (KISS), with minimal validation (PHP type errors only) to reduce complexity in the library and maximize performance for consumer developers. Therefore, please make sure to add your own validation if using user inputs in any database queries.\n\n## Features\n\n- Easy to configure for your project's entities\n- Supporting scalar types, array, and date/time and relationships `Many-to-One`, `One-to-Many` and `One-to-One`\n- Fluent, chainable API for CRUD operations, using integrated query builder from [jpi/query](https://packagist.org/packages/jpi/query)\n\n## Dependencies\n\n- PHP 8.0+\n- Composer\n- PHP PDO\n- MySQL 5+\n- [jpi/database](https://packagist.org/packages/jpi/database) v2\n- [jpi/query](https://packagist.org/packages/jpi/query) v2\n\n## Installation\n\nUse [Composer](https://getcomposer.org/)\n\n```bash\n$ composer require jpi/orm \n```\n\n### Properties and Methods for Setup\n\nYou will need to extend `\\JPI\\ORM\\Entity` and then define the following:\n\n#### `getDatabase(): \\JPI\\Database`\n\nThis method must be implemented to provide the database connection for this entity. `\\JPI\\Database` is just an extension of `PDO` - you can find out more [here](https://packagist.org/packages/jpi/database).\n\n#### `$table: string`\n\nThe database table name for this entity.\n\n#### `$dataMapping: array`\n\nThis array defines the structure of your entity and maps to your database columns. Each key is a column name and the value is an array with:\n\n- `type` (required): One of: `string`, `int`, `float`, `array`, `date`, `date_time`, `belongs_to`, `has_one`, `has_many`\n- `default_value`\n- `separator`: The separator for `array` type columns when stored as delimited strings (defaults to `\",\"`)\n- `entity`: The related entity class name (required for relationship types)\n- `column`\n    - The database column behind this for `belongs_to` type (defaults to `{key}_id`)\n    - The key in related entity for `has_many` \u0026 `has_one` types that links back to this\n- `cascade_delete`: Whether to delete related entities when this entity is deleted (for `has_one` and `has_many` types)\n- `cascade_clone`: Whether to clone related entities when this entity is cloned via `clone` - essentially creates new records with same data, else it sets to null/empty (for `has_one` and `has_many` types)\n\n```php\nprotected static array $dataMapping = [\n    \"name\" =\u003e [\n        \"type\" =\u003e \"string\",\n    ],\n    \"sku\" =\u003e [\n        \"type\" =\u003e \"string\",\n    ],\n    \"price\" =\u003e [\n        \"type\" =\u003e \"float\",\n        \"default_value\" =\u003e 0.00,\n    ],\n    \"categories\" =\u003e [\n        \"type\" =\u003e \"array\",\n        \"separator\" =\u003e \",\", // Optional, defaults to \",\"\n    ],\n    \"created_at\" =\u003e [\n        \"type\" =\u003e \"date_time\",\n    ],\n];\n```\n\n#### `$columnPrefix: string` - optional\n\nSome database designers like to prefix their table columns. For example, the `products` table might have columns like `product_id` \u0026 `product_name` instead of `id` \u0026 `name`. Set this property to add that prefix automatically.\n\nNote: the first underscore is required.\n\n#### `$defaultOrderByColumn: string` - optional\n\nThe default column to order results by when selecting records and haven't specified an order. Default is `id`.\n\n#### `$defaultOrderByASC: bool` - optional\n\nWhether the default ordering should be ascending. Default is `true`.\n\n### Complete Example\n\n```php\n...\nclass Product extends \\JPI\\ORM\\Entity {\n\n    protected static string $table = \"products\";\n\n    protected static array $dataMapping = [\n        \"name\" =\u003e [\n            \"type\" =\u003e \"string\",\n        ],\n        \"sku\" =\u003e [\n            \"type\" =\u003e \"string\",\n        ],\n        \"price\" =\u003e [\n            \"type\" =\u003e \"float\",\n        ],\n        \"stock\" =\u003e [\n            \"type\" =\u003e \"int\",\n        ],\n        \"created_at\" =\u003e [\n            \"type\" =\u003e \"date_time\",\n        ],\n    ];\n\n    public static function getDatabase(): \\JPI\\Database {\n        return new \\JPI\\Database(\"mysql:host=localhost;dbname=shop\", \"username\", \"password\");\n    }\n\n    ...\n}\n```\n## Relationships\n\nThe ORM supports three types of relationships:\n\n#### `belongs_to` - Many-to-One\n\n```php\nclass Order extends Entity {\n    ...\n    protected static array $dataMapping = [\n        ...\n        \"customer\" =\u003e [\n            \"type\" =\u003e \"belongs_to\",\n            \"entity\" =\u003e Customer::class,\n            \"column\" =\u003e \"customer\", // Defaults to \"customer_id\" if not specified\n        ],\n        ...\n    ];\n    ...\n}\n\n$order = Order::getById(1);\n$customer = $order-\u003ecustomer; // Lazy loads the Customer entity\n```\n\n#### `has_many` - One-to-Many\n\n```php\nclass Order extends Entity {\n    ...\n    protected static array $dataMapping = [\n        ...\n        \"items\" =\u003e [\n            \"type\" =\u003e \"has_many\",\n            \"entity\" =\u003e OrderItem::class,\n            \"column\" =\u003e \"order\", // The key in OrderItem that links back\n            \"cascade_delete\" =\u003e true,\n        ],\n        ...\n    ];\n    ...\n}\n\n$order = Order::getById(1);\n$items = $order-\u003eitems; // Lazy loads a Collection of OrderItem entities\n```\n\n#### `has_one` - One-to-One\n\n```php\nclass Order extends Entity {\n    ...\n    protected static array $dataMapping = [\n        ...\n        \"payment\" =\u003e [\n            \"type\" =\u003e \"has_one\",\n            \"entity\" =\u003e Payment::class,\n            \"column\" =\u003e \"order\",\n            \"cascade_delete\" =\u003e true,\n        ],\n        ...\n    ];\n    ...\n}\n\n$order = Order::getById(1);\n$payment = $order-\u003epayment; // Lazy loads the Payment entity\n```\n\n## Usage\n\n### Retrieving Entities\n\n**`getById(int $id): ?static`** - Get an entity by its ID.\n\n**`newQuery(): QueryBuilder`** - Get a query builder instance for advanced queries. See [Query Builder](#query-builder) section for examples.\n\n### Accessing Entity Data\n\nYou can get and set entity values using simple property access, these are the keys from `$dataMapping`. When setting the value must be value for the type defined or null.\n\n### Creating and Saving Entities\n\n**`factory(?array $data = null): static`** - Create a new entity instance, and optionally set initial data in one call.\n\n**`insert(array $data): static`** - Create and save an entity in one call.\n\n**`save(): bool`** - Save (insert or update) the entity to the database.\n\n### Deleting Entities\n\n**`delete(): bool`** - Delete the entity from the database.\n\n### Utility Methods\n\n**`isLoaded(): bool`** - Check if the entity has been loaded from or saved to the database.\n\n**`isDeleted(): bool`** - Check if the entity has been deleted.\n\n**`toArray(): array`** - Convert the entity to an array.\n\n**`reload(): void`** - Reload the entity from the database.\n\n## Query Builder\n\nThe query builder (accessed via `newQuery()`) provides a fluent interface for building database queries. It uses `\\JPI\\Database\\Query\\Builder` from [jpi/query](https://packagist.org/packages/jpi/query), see documentation there for full details on available query methods.\n\n### Eager Loading\n\nTo avoid N+1 query problems, you can eager load relationships using the `with()` method:\n\n```php\n// Eager load a single relationship\n$orders = Order::newQuery()-\u003ewith(\"customer\")-\u003eselect();\n\n// Eager load multiple relationships\n$orders = Order::newQuery()-\u003ewith(\"customer\", \"items\")-\u003eselect();\n\n// Eager load nested relationships\n$orders = Order::newQuery()-\u003ewith(\"customer.address\")-\u003eselect();\n\n// Combine with other query methods\n$orders = Order::newQuery()\n    -\u003ewhere(\"status\", \"=\", \"completed\")\n    -\u003eorderBy(\"created_at\", false)\n    -\u003ewith(\"customer\", \"items\")\n    -\u003eselect();\n```\n\nWithout eager loading, accessing relationships causes a separate query for each entity (N+1 problem). With eager loading, all related entities are fetched in a single optimized query.\n\n### Lazy Eager Loading\n\nIf you already have a collection of entities and later need to load relationships, use the `load()` method:\n\n```php\n// Get orders without relationships\n$orders = Order::newQuery()-\u003ewhere(\"status\", \"=\", \"completed\")-\u003eselect();\n\n// Later, load relationships on the collection\n$orders-\u003eload(\"customer\");\n\n// Or load multiple relationships\n$orders-\u003eload(\"customer\", \"items\");\n\n// Nested relationships work too\n$orders-\u003eload(\"customer.address\");\n```\n\nThis is useful when you receive a collection from another part of your application and need to load relationships efficiently. Like `with()`, it prevents N+1 query problems by batching relationship queries instead of loading them one at a time.\n\n## Support\n\nIf you found this library interesting or useful please spread the word about this library: share on your socials, star on GitHub, etc.\n\nIf you find any issues or have any feature requests, you can open a [issue](https://github.com/jahidulpabelislam/orm/issues) or email [me @ jahidulpabelislam.com](mailto:me@jahidulpabelislam.com) :smirk:.\n\n## Authors\n\n- [Jahidul Pabel Islam](https://jahidulpabelislam.com/) [\u003cme@jahidulpabelislam.com\u003e](mailto:me@jahidulpabelislam.com)\n\n## Licence\n\nThis module is licensed under the General Public Licence - see the [licence](LICENSE.md) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahidulpabelislam%2Form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjahidulpabelislam%2Form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahidulpabelislam%2Form/lists"}