Cycle ORM can be installed into any PHP application using composer dependency manager.
Cycle ORM is available as a composer package and can be installed using the following command in the root of your project:
$ composer require cycle/orm
In order to enable support for annotated entities you have to install an additional package:
$ composer require cycle/annotated
This command will also download Cycle ORM dependencies such as spiral/database, doctrine/collections and zendframework/zend-hydrator.
In order to access Cycle ORM classes make sure to include vendor/autoload.php in your file.
<?php declare(strict_types=1);
include 'vendor/autoload.php';
In order to connect Cycle to the proper database instance, you must configure the instance of Cycle\Database\DatabaseManager.
The details of this configuration process described in a following section.
An ORM service can be instantiated using the Cycle\ORM\ORM class, which takes only one dependency on Cycle\ORM\Factory:
use Cycle\ORM;
$orm = new ORM\ORM(new ORM\Factory($dbal));
In order to operate Cycle ORM a schema definition is required. The schema will contain a list of available entities, their relations, and association with a specific database.
The schema can be described manually by instantiating Cycle\ORM\Schema object:
use Cycle\ORM\Schema;
use Cycle\ORM\Relation;
use Cycle\ORM\Mapper\Mapper;
$schema = new Schema([
'user' => [
Schema::ENTITY => User::class,
Schema::MAPPER => Mapper::class,
Schema::DATABASE => 'default',
Schema::TABLE => 'user',
Schema::PRIMARY_KEY => 'id',
Schema::COLUMNS => [
'id' => 'id',
'email' => 'email',
'balance' => 'balance'
],
Schema::TYPECAST => [
'id' => 'int',
'balance' => 'float'
],
Schema::SCHEMA => [],
Schema::RELATIONS => [
'address' => [
Relation::TYPE => Relation::HAS_ONE,
Relation::TARGET => 'address',
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::INNER_KEY => 'id',
Relation::OUTER_KEY => 'user_id',
],
]
]
],
'address' => [
Schema::ENTITY => Address::class,
Schema::MAPPER => Mapper::class,
Schema::DATABASE => 'default',
Schema::TABLE => 'address',
Schema::PRIMARY_KEY => 'id',
Schema::COLUMNS => [
'id' => 'id',
'user_id' => 'user_id',
'city' => 'city'
],
Schema::TYPECAST => [
'id' => 'int'
],
Schema::SCHEMA => [],
Schema::RELATIONS => []
],
]);
$orm = $orm->withSchema($schema);
However, in order to simplify the integration, it is recommended to use a schema compiler provided by cycle/schema-builder extension. Such compiler is able to automatically index all available entities, perform database introspection and reflection.
To compile the schema using annotated entities and automatically configure the database use the following pipeline:
use Cycle\Schema;
use Cycle\Annotated;
use Spiral\Tokenizer;
// Class locator
$cl = (new Tokenizer\Tokenizer(new Tokenizer\Config\TokenizerConfig([
'directories' => ['src/'],
])))->classLocator();
$schema = (new Schema\Compiler())->compile(new Schema\Registry($dbal), [
new Annotated\Embeddings($cl), // register embeddable entities
new Annotated\Entities($cl), // register annotated entities
new Schema\Generator\ResetTables(), // re-declared table schemas (remove columns)
new Annotated\MergeColumns(), // copy column declarations from all related classes (@Table annotation)
new Schema\Generator\GenerateRelations(), // generate entity relations
new Schema\Generator\ValidateEntities(), // make sure all entity schemas are correct
new Schema\Generator\RenderTables(), // declare table schemas
new Schema\Generator\RenderRelations(), // declare relation keys and indexes
new Annotated\MergeIndexes(), // copy index declarations from all related classes (@Table annotation)
new Schema\Generator\SyncTables(), // sync table changes to database
new Schema\Generator\GenerateTypecast(), // typecast non string columns
]);
$orm = $orm->withSchema(new \Cycle\ORM\Schema($schema));
The result of the schema builder is a compiled schema. The given schema can be cached in order to avoid expensive calculations on each request.
In the following section the terming
update schemawill be referenced to this process.
Remove element new Schema\Generator\SyncTables() to disable database reflection. In a later section, we will describe how to automatically render database migrations instead of direct synchronization.