cycle/annotated

Cycle ORM Annotated Entities generator

Maintainers

👁 wolfy-j

Package info

github.com/cycle/annotated

Homepage

Chat

Documentation

pkg:composer/cycle/annotated

Fund package maintenance!

cycle

Statistics

Installs: 791 405

Dependents: 56

Suggesters: 3

Stars: 28

Open Issues: 10

v4.6.0 2026-06-15 20:56 UTC

Requires

Requires (Dev)

Suggests

None

Provides

None

Conflicts

None

Replaces

None

MIT e04328c7e532ba109c3a3cfd21856f63bacf3453

  • Anton Titov (wolfy-j) <wolfy-j.woop@spiralscout.com>
  • Aleksei Gagarin
  • Pavel Butchnev
  • Maksim Smakouz (msmakouz) <maksim.smakouz.woop@spiralscout.com>

README

👁 PHP Version Require
👁 Latest Stable Version
👁 phpunit
👁 psalm
👁 psalm-level
👁 Codecov
👁 Total Downloads
👁 Image

Documentation | Cycle ORM

The package provides the ability to define Cycle ORM schema using PHP attributes.

Usage

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Column;

#[Entity]
class User
{
 #[Column(type: 'primary')]
 private int $id;

 #[Column(type: 'string(32)')]
 private string $login;

 #[Column(type: 'enum(active,disabled)')]
 private string $status;

 #[Column(type: 'decimal(5,5)')]
 private $balance;
}

Relations

HasOne

use Cycle\Annotated\Annotation\Relation\HasOne;
use Cycle\Annotated\Annotation\Entity;

#[Entity]
class User
{
 // ...

 #[HasOne(target: Address::class)]
 public ?Address $address;
}

Note Read more about HasOne.

HasMany

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\HasMany;

#[Entity]
class User
{
 // ...

 #[HasMany(target: Post::class)]
 private array $posts;
}

Note Read more about HasMany.

BelongsTo

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\BelongsTo;

#[Entity]
class Post
{
 // ...

 #[BelongsTo(target: User::class)]
 private User $user;
}

Note Read more about BelongsTo.

RefersTo

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\RefersTo;
use Cycle\Annotated\Annotation\Relation\HasMany;

#[Entity]
class User
{
 // ...

 #[RefersTo(target: Comment::class)]
 private ?Comment $lastComment;

 #[HasMany(target: Comment::class)]
 public array $comments;

 // ...

 public function addComment(Comment $c): void
 {
 $this->lastComment = $c;
 $this->comments[] = $c;
 }
 
 public function removeLastComment(): void
 {
 $this->lastComment = null;
 }
 
 public function getLastComment(): ?Comment
 {
 return $this->lastComment;
 }
}

Note Read more about RefersTo.

ManyToMany

use Cycle\Annotated\Annotation\Relation\ManyToMany;
use Cycle\Annotated\Annotation\Entity;

#[Entity]
class User
{
 // ...

 #[ManyToMany(target: Tag::class, through: UserTag::class)]
 protected array $tags;
 
 public function getTags(): array
 {
 return $this->tags;
 }
 
 public function addTag(Tag $tag): void
 {
 $this->tags[] = $tag;
 }
 
 public function removeTag(Tag $tag): void
 {
 $this->tags = array_filter($this->tags, static fn(Tag $t) => $t !== $tag);
 }
}

Note Read more about ManyToMany.

Embedded Entities

use Cycle\Annotated\Annotation\Embeddable;
use Cycle\Annotated\Annotation\Column;
use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\Embedded;

#[Embeddable]
class UserCredentials
{
 #[Column(type: 'string(255)')]
 public string $username;

 #[Column(type: 'string')]
 public string $password;
}

#[Entity]
class User
{
 #[Column(type: 'primary')]
 public int $id;

 #[Embedded(target: 'UserCredentials')]
 public UserCredentials $credentials;

 public function __construct()
 {
 $this->credentials = new UserCredentials();
 }
}

Note Read more about Embedded Entities.

BelongsToMorphed

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\Morphed\BelongsToMorphed;

#[Entity]
class Image
{
 // ...

 #[BelongsToMorphed(taget: ImageHolderInterface::class)]
 public ImageHolderInterface $imageHolder;
}

Note Read more about BelongsToMorphed.

MorphedHasOne

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\Morphed\MorphedHasOne;

#[Entity]
class User
{
 // ...

 #[MorphedHasOne(target: Image::class)]
 public $image;
}

Note Read more about MorphedHasOne.

MorphedHasMany

use Cycle\Annotated\Annotation\Entity;
use Cycle\Annotated\Annotation\Relation\Morphed\MorphedHasMany;

#[Entity]
class User
{
 // ...

 #[MorphedHasMany(target: Image::class)]
 public $images;
}

Note Read more about MorphedHasMany.

Single Table Inheritance

#[Entity]
#[DiscriminatorColumn(name: 'type')] // Discriminator column (required)
class Person
{
 #[Column(type: 'primary', primary: true)]
 protected int $id;

 #[Column(type: 'string')]
 protected string $name;
}

#[Entity]
#[InheritanceSingleTable]
class Employee extends Person
{
 #[Column(type: 'int')]
 protected int $salary;
}

#[Entity]
#[InheritanceSingleTable(value: 'foo_customer')]
class Customer extends Person
{
 #[Column(type: 'json')]
 protected array $preferences;
}

Note Read more about Single Table Inheritance.

Joined Table Inheritance

#[Entity]
class Person
{
 #[Column(primary: true)]
 protected int $id;
 
 #[Column()]
 protected int $fooId;

 #[Column(type: 'string')]
 protected string $name;
}

#[Entity]
#[InheritanceJoinedTable(outerKey: 'fooId')]
class Employee extends Person
{
 #[Column(type: 'int')]
 protected int $salary;
}

#[Entity]
#[InheritanceJoinedTable(outerKey: 'id')]
class Customer extends Person
{
 #[Column(type: 'json')]
 protected array $preferences;
}

Note Read more about Joined Table Inheritance.

License

The MIT License (MIT). Please see LICENSE for more information. Maintained by Spiral Scout.