{"id":17797381,"url":"https://github.com/steevanb/doctrine-read-only-hydrator","last_synced_at":"2025-05-10T20:02:28.186Z","repository":{"id":9490526,"uuid":"62292550","full_name":"steevanb/doctrine-read-only-hydrator","owner":"steevanb","description":"Add SimpleObject and ReadOnly hydrators do Doctrine.","archived":false,"fork":false,"pushed_at":"2022-06-20T12:35:49.000Z","size":91,"stargazers_count":58,"open_issues_count":7,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-09T13:09:07.829Z","etag":null,"topics":["doctrine","php","symfony"],"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/steevanb.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":"2016-06-30T08:10:44.000Z","updated_at":"2024-10-30T13:13:01.000Z","dependencies_parsed_at":"2022-08-24T13:46:12.889Z","dependency_job_id":null,"html_url":"https://github.com/steevanb/doctrine-read-only-hydrator","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steevanb%2Fdoctrine-read-only-hydrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steevanb%2Fdoctrine-read-only-hydrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steevanb%2Fdoctrine-read-only-hydrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steevanb%2Fdoctrine-read-only-hydrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steevanb","download_url":"https://codeload.github.com/steevanb/doctrine-read-only-hydrator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253256465,"owners_count":21879270,"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":["doctrine","php","symfony"],"created_at":"2024-10-27T11:55:35.703Z","updated_at":"2025-05-09T13:09:20.424Z","avatar_url":"https://github.com/steevanb.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![version](https://img.shields.io/badge/version-2.3.0-green.svg)](https://github.com/steevanb/doctrine-read-only-hydrator/tree/2.3.0)\n[![doctrine](https://img.shields.io/badge/doctrine/orm-^2.4.8-blue.svg)](http://www.doctrine-project.org)\n[![php](https://img.shields.io/badge/php-^5.4.6%20||%20^7.0||%20^8.0-blue.svg)](http://www.doctrine-project.org)\n![Lines](https://img.shields.io/badge/code%20lines-1331-green.svg)\n![Total Downloads](https://poser.pugx.org/steevanb/doctrine-read-only-hydrator/downloads)\n[![Scrutinizer](https://scrutinizer-ci.com/g/steevanb/doctrine-read-only-hydrator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/steevanb/doctrine-read-only-hydrator/)\n\n## doctrine-read-only-hydrator\n\nWhen you retrieve data with Doctrine, you can get an array with values, or a fully hydrated object.\n\nHydration is a very slow process, who return same instance of entity if several hydrations have same entity to hydrate. \nIt's fine when you want to insert / update / delete your entity. But when you just want to retrieve data without editing\nit (to show it in list for example), it's way to slow.\n\nIf you want to really retrieve data from your database, and don't get UnitOfWork reference : with Doctrine hydration you can't.\nEach query will not hydrate a new entity with data taken in your query result, it will return the first hydrated entity, known by UnitOfWork.\n\nSo, in case you don't need to modify your entity, you want to be really faster, or just retrieve data stored in your\ndatabase, you can use SimpleObjectHydrator or ReadOnlyHydrator.\n\nThis hydrated entities can't be persisted / flushed, because they are not registered in UnitOfwork to be faster.\n\nNothing will be lazy loaded : to be faster, and because most of the time, you have to create a complete QueryBuilder,\nwho return everything you need.\n\n[Changelog](changelog.md)\n\n## Benchmark\n\nThis table show simple benchmark results (time and memory_get_peak_usage()), with 30, 1000 and 5000 entities retrieved\nfrom a MySQL 5.7 database, PHP 5.6.23 and Doctrine 2.5.4.\n\nArrayHydrator is used when you call $query-\u003egetArrayResult(), ObjectHydrator when you call $query-\u003egetResult(),\n$repository-\u003efindAll() or $repository-\u003efindBy().\n\nSimpleObjectHydrator and ReadOnlyHydrator are provided with this lib, see example above.\n\n| Entities | SQL request | ArrayHydrator    | SimpleObjectHydrator | ReadOnlyHydrator | ObjectHydrator   |\n| -------- | ----------- | ---------------- | -------------------- | ---------------- | ---------------- |\n| 30       | 0.26ms      | 1.05 ms, 28 mo   | 1.45 ms, 28 mo       | 1.78 ms, 28 mo   | 7.94 ms, 29 mo   |\n| 1000     | 1.58 ms     | 29.75 ms, 32 mo  | 37.01 ms, 29 mo      | 43.26 ms, 32 mo  | 113.45 ms, 41 mo |\n| 5000     | 6.36 ms     | 164.76 ms, 48 mo | 187.30 ms, 32 mo     | 228.89 ms, 46 mo | 671.82 ms, 90 mo |\n\n![benchmark](benchmark.png)\n\nYou can see hydration process is really slow ! For 5 000 entities, Doctrine ObjectHydrator is 100x slower than the SQL request...\n\nAs expected, getArrayResult() is the fastest way to retrieve data.\nBut, you have to work with array, so you can't use entity methods.\n\nReadOnlyHydrator is 4x faster than Doctrine ObjectHydrator, and only 40% slower than ArrayHydrator (who is hard to use).\n\nIs you want to be as fast as possible, but with an entity result instead of an array, SimpleObjectHydrator looks pretty good.\n\n## SimpleObjectHydrator\n\n* Hydrate your entity, with all selected fields in your QueryBuilder. If you try to access a non-loaded property,\nno exception will be throwned, you can call all accessors.\n* No lazy loading will be executed.\n* You can't persist or flush this entity.\n* Usefull when you want to be faster than Doctrine ObjectHydrator (and a little little bit more than ReadOnlyHydrator),\nyou don't want to insert / update this entity, but doesn't ensure you can't access non-loaded property.\n\n## ReadOnlyHydrator\n\n* Hydrate a proxy of your entity, who throw an exception if you try to access a property who is not loaded by your QueryBuilder.\n* No lazy loading will be executed.\n* You can't persist or flush this entity.\n* Usefull when you want to be faster than Doctrine ObjectHydrator, you don't want to insert / update this entity, and\nbe \"sure\" any access to a non-loaded property will throw an exception.\n\n## Example\n\n```php\n# Foo\\Repository\\BarRepository\n\nuse steevanb\\DoctrineReadOnlyHydrator\\Hydrator\\ReadOnlyHydrator;\n\nclass BarRepository\n{\n    public function getReadOnlyUser($id)\n    {\n        return $this\n            -\u003ecreateQueryBuilder('user')\n            -\u003eselect('user', 'PARTIAL comments.{id, comment}')\n            -\u003ejoin('user.comments', 'comments')\n            -\u003ewhere('user.id = :id')\n            -\u003esetParameter('id', $id)\n            -\u003egetQuery()\n            -\u003egetResult(ReadOnlyHydrator::HYDRATOR_NAME);\n    }\n}\n```\n\n## Installation\n\n```bash\ncomposer require steevanb/doctrine-read-only-hydrator ^2.3\n```\n\n### Symfony 2.x or 3.x integration\n\n```php\n# app/AppKernel.php\n\nclass AppKernel extends Kernel\n{\n    public function registerBundles()\n    {\n        $bundles = [\n            new steevanb\\DoctrineReadOnlyHydrator\\Bridge\\ReadOnlyHydratorBundle\\ReadOnlyHydratorBundle()\n        ];\n    }\n}\n```\n\n### Symfony 4.x or 5.x integration\n\n```php\n# config/bundles.php\n\nreturn [\n    steevanb\\DoctrineReadOnlyHydrator\\Bridge\\ReadOnlyHydratorBundle\\ReadOnlyHydratorBundle::class =\u003e ['all' =\u003e true],\n];\n\n```\n\n### Manual integration\n\nYou need to register `SimpleObjectHydrator` and `ReadOnlyHydrator` to `Doctrine\\ORM\\Configuration`:\n\n```php\nuse steevanb\\DoctrineReadOnlyHydrator\\Hydrator\\SimpleObjectHydrator;\nuse steevanb\\DoctrineReadOnlyHydrator\\Hydrator\\ReadOnlyHydrator;\n\n$configuration-\u003eaddCustomHydrationMode(SimpleObjectHydrator::HYDRATOR_NAME, SimpleObjectHydrator::class);\n$configuration-\u003eaddCustomHydrationMode(ReadOnlyHydrator::HYDRATOR_NAME, ReadOnlyHydrator::class);\n```\n\n### Integration with steevanb/doctrine-stats\n\n[steevanb/doctrine-stats](https://github.com/steevanb/doctrine-stats) add lots of statistics about Doctrine :\nnumber of mapped entities, number of lazy loaded entities, collapse and count same sql queries, show hydration time etc.\n\nIf you use this lib, you have to add SimpleObjectHydrator and ReadOnlyHydrator hydration times :\n```json\n# composer.json\n\n{\n    \"extra\": {\n        \"composer-overload-class-dev\": {\n            \"steevanb\\\\DoctrineReadOnlyHydrator\\\\Hydrator\\\\SimpleObjectHydrator\": {\n                \"original-file\": \"vendor/steevanb/doctrine-read-only-hydrator/Hydrator/SimpleObjectHydrator.php\",\n                \"overload-file\": \"vendor/steevanb/doctrine-read-only-hydrator/ComposerOverloadClass/Hydrator/SimpleObjectHydrator.php\"\n            },\n            \"steevanb\\\\DoctrineReadOnlyHydrator\\\\Hydrator\\\\ReadOnlyHydrator\": {\n                \"original-file\": \"vendor/steevanb/doctrine-read-only-hydrator/Hydrator/ReadOnlyHydrator.php\",\n                \"overload-file\": \"vendor/steevanb/doctrine-read-only-hydrator/ComposerOverloadClass/Hydrator/ReadOnlyHydrator.php\"\n            }\n        }\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteevanb%2Fdoctrine-read-only-hydrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteevanb%2Fdoctrine-read-only-hydrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteevanb%2Fdoctrine-read-only-hydrator/lists"}