thewunder / corma
Convention-based Alternative ORM
5.2.0
2025-09-19 16:02 UTC
Requires
- php: >=8.1
- ext-json: *
- ext-pdo: *
- doctrine/inflector: ^1.3||^2.0
- psr/container: ^2.0
- psr/event-dispatcher: ^1.0
- psr/simple-cache: ^2.0||^3.0
- thewunder/corma-dbal: ^1.0
Requires (Dev)
- phpunit/phpunit: ^10.0
- rector/rector: ^1.0
- symfony/event-dispatcher: ^6.0 || ^7.0
- vlucas/phpdotenv: ~2.0
Suggests
This package is auto-updated.
Last update: 2026-06-09 17:31:33 UTC
README
Corma is a high-performance, convention-based ORM based on Doctrine DBAL.
Corma is great because:
- No complex and difficult to verify annotations or configuration files
- Promotes consistent code organization
- Loads and saves one-to-one, one-to-many, many-to-many, and polymorphic relationships
- Can save multiple objects in a single query (using an upsert)
- Makes it easy to cache and avoid database queries
- Supports soft deletes
- Makes it easy to handle transactions in a Unit of Work
- Highly customizable
Corma doesn't:
- Autoload or lazy load relationships by default
- Do migrations or code generation
Works in MySql and PostgreSQL.
Install via Composer
Via the command line:
composer.phar require thewunder/corma ^5.0
Or add the following to the require section your composer.json:
"thewunder/corma": "^5.0"
For PHP versions < 8.1 use Corma version ~3.0
Basic Usage
Create a DataObject
namespace YourNamespace\Dataobjects; use Corma\Relationship\ManyToMany; use Corma\Relationship\OneToMany; use Corma\Relationship\OneToOne; class YourDataObject { protected $id; //If the property name == column name on the table your_data_objects it will be saved protected $myColumn; protected ?int $otherObjectId = null; #[OneToOne] protected ?OtherObject $otherObject = null; #[OneToMany(AnotherObject::class)] protected ?array $anotherObjects = null; #[ManyToMany(DifferentObject::class, 'your_data_object_different_link_table')] protected ?array $differentObjects = null; //Getters and setters.. }
And a Repository (optional)
namespace YourNamespace\Dataobjects\Repository; class YourDataObjectRepository extends ObjectRepository { //Override default behavior and add custom methods... }
Create the orm and use it
$db = DriverManager::getConnection(...); //see Doctrine DBAL docs $orm = ObjectMapper::withDefaults($db, $container); //uses any PSR-11 compatible DI container $object = $orm->create(YourDataObject::class); //Call setters... $orm->save($object); //Call more setters... $orm->save($object); //Call more setters on $object... $objects = [$object]; $newObject = $orm->create(YourDataObject::class); //call setters on $newObject... $objects[] = $newObject; $orm->saveAll($objects); //find existing object by id $existingObject = $orm->find(YourDataObject::class, 5); //find existing objects with myColumn >= 42 AND otherColumn = 1 $existingObjects = $orm->findBy(YourDataObject::class, ['myColumn >='=>42, 'otherColumn'=>1], ['sortColumn'=>'ASC']); //load relationships $orm->load($existingObjects, 'otherObject'); $orm->load($existingObjects, 'anotherObjects'); $orm->load($existingObjects, 'differentObjects'); //delete those $orm->deleteAll($existingObjects);
Documentation
See the wiki for full documentation.
Contributing
Please see CONTRIBUTING for details.