PHPackages                             computools/clight-orm - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. computools/clight-orm

ActiveLibrary[Database &amp; ORM](/categories/database)

computools/clight-orm
=====================

Light ORM

v0.6.5(7y ago)0121MITPHPPHP ^7.1

Since Jul 10Pushed 7y ago1 watchersCompare

[ Source](https://github.com/computools/clight-orm)[ Packagist](https://packagist.org/packages/computools/clight-orm)[ Docs](https://github.com/computools/clight-orm)[ RSS](/packages/computools-clight-orm/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependencies (1)Versions (34)Used By (0)

CLight ORM
==========

[](#clight-orm)

This library designed as usual ORM.

Purpose for ORM development was to create fast and convenient tool for working with database and relation mapping. ORM allows you to link entities with One-To-Many, One-To-One, Many-To-One, Many-To-Many relation types.

Installation
============

[](#installation)

```
composer require computools/clight-orm

```

Structural elements:
====================

[](#structural-elements)

- **Entity** - representation of database table. This objects must have getters and setters for properties and extends *AbstractEntity* from library.
- **Repository** - based on Repository Pattern, this objects must have Entity objects definition and be extended from *AbstractRepository*. Abstract repository contains all common (like find, findBy, etc) methods for data search and saving.

Examples
========

[](#examples)

For examples you may look at *tests* directory.

Lets have a look:

Entity
------

[](#entity)

*AbstractEntity* inheritance involves implementation of *getTable()* method, that will define database table name and *getFields()* method, that returns array of rules.

Also, you can provide some optional fields that will be mapped if field presents in query result only. For example we can add some *count* field that will not be related to table, but will present in query result.

For that puproses you can use *getOptionalFields()* method.

Keys must be specified as table column names.

### Allowed field types:

[](#allowed-field-types)

- **IdType** with optional parameter 'identifierField', that need to be specified if tables identifier column name is not 'id'
- **IntegerType** - integer, with optional parameter 'columnName', if map field is different than database field.
- **StringType** - string or text, with optional parameter 'columnName', if map field is different than database field.
- **FloatType** - float or decimal, with optional parameter 'columnName', if map field is different than database field.
- **DateTimeType** - datetime with column name as first argument and format as second.
- **CreatedAtType** - datetime, value will be defined automatically while entity creation. First parameter is columnName, second - datetime format, both are optional.
- **UpdatedAtType** - datetime, value will be defined automatically while entity is updating. First parameter is columnName, second - datetime format, both are optional.
- **BooleanType** - boolean, first parameter is column name if different than table field name, second parameter defines if field must be saved as int (default is true).
- **JsonType** - json, saves json to database and convert to array for entity. First parameter - table field name.

### Allowed relation types:

[](#allowed-relation-types)

- **OneToOne** - first parameter is related entity instance, second is main table field name
- **ManyToOne** - first parameter is related entity instance, second is main table field name.
- **OneToMany** - first parameter is related entity instance, second is related table field.
- **ManyToMany** - with parameters:

    - entity - related entity instance
    - table - many-to-many relation table name
    - columnName - relation table column name that corresponds main table
    - referencedColumnName - relation table column name that corresponds referenced table

    use Computools\\CLightORM\\Entity\\AbstractEntity;

    class Book extends AbstractEntity { public function getTable(): string { return 'books'; }

    ```
      public function getFields(): array
      {
          return [
              'id' => new IdType(),
              'name' => new StringType('title'),
              'price' => new FloatType(),
              'authors' => new ManyToMany(new Author(), 'authors_books', 'book_id', 'author_id'),
              'themes' => new ManyToMany(new Theme(), 'books_theme', 'book_id', 'theme_id')
          ];
      }

      public functnion getOptionalFields(): array
      {
          return [
              'themes_count' => new IntegerType()
          ];
      }

      private $id;

      private $name;

      private $authors = [];

      private $themes = [];

      private $price;

      private $themesCount;

      public function getThemesCount()
      {
          return $this->themesCount;
      }

      public function getId(): ?int
      {
          return $this->id;
      }

      public function getName(): ?tring
      {
          return $this->name;
      }

      public function setName(?string $name): void
      {
          $this->name = $name;
      }

      public function getAuthors(): array
      {
          return $this->authors;
      }

      public function getThemes(): array
      {
          return $this->themes;
      }

      public function getPrice(): ?float
      {
          return $this->price;
      }

      public function setPrice(float $price)
      {
          $this->price = $price;
      }

    ```

    }

Id field must have ability to take null in case of new entity, that have not been saved to database yet.

Another option is using public properties instead of getters and setters. This library supports that kind of entities.

```
use Computools\CLightORM\Entity\AbstractEntity;

class Book extends AbstractEntity
{
    public $id;

    public $name;

    public $authors;

    public $themes;

    public $price;
}

```

If you want to set null to one-to-one or many-to-one relation you can use *destroyToOneRelation(string $field)* method:

```
$post->destroyToOneRelation('author');
$postRepository->save();

```

This operation will save null to author\_id field for post record. This can be used regardless method that was used to receive entity. So both will work:

```
$postRepository->find(1, ['author']);
$post->destroyToOneRelation('author');

$postRepository->find(1);
$post->destroyToOneRelation('author');

```

If you want to add many-to-many relation for two entities, you can call *addRelation(EntityInterface $entity)* method and *removeRelation(EntityInterface $entity)* to remove.

```
$post->addRelation($user);

$post->removeRelation($user);

```

ORM has ability to execute mass assignment for entity. So you can use this construction

```
$book = new Book();
$book->fill([
    'name' => 'Book name',
    'price' => 10.99
]);
$bookRepository->save($book);

```

instead of

```
$book = new Book();
$book->setName('Book name');
$book->setPrice(10.99);
$bookRepository->save($book);

```

That kind of action will be allowed if $allowedFields property was set for entity. So it will looks like

```
class Book
{
    protected $allowedFields = [
        'name',
        'price'
    ];

    public $name;

    public $price;
}

```

This is list of fields, that can be set with fill() method. If specified field is not presents in the list - it will be skipped.

Repository
----------

[](#repository)

```
use Computools\CLightORM\Repository\AbstractRepository;
use Computools\CLightORM\Test\Entity\Book;

class BookRepository extends AbstractRepository
{
    public function getEntityClass(): string
    {
        return Book::class;
    }

    public function findByUser(User $user): ?Book
    {
        return $this->findBy(['user_id' => $user->getId()]);
    }
}

```

This is the way how repository must be implemented. You can write your own methods or use existed.

To call the repository, you can use

***Computools\\CLightORM\\CLightORM***

Here is the example:

```
$pdo = new \PDO(
            sprintf(
                '%s:host=%s;port=%s;dbname=%s',
                'mysql',
                '127.0.0.1',
                '3306',
                'test'
            ),
        'user',
        'password'
        );

$clightORM = new CLightORM($pdo);

```

To get certain entity repository just call create method with class string as argument:

```
$repository = $clightORM->createRepository(PostRepository::class);
$repository->find(2);

```

### Repository methods

[](#repository-methods)

- find(int $id, array $with, $expiration = 0)
- findBy(array $citeria, ?Order $order, array $with, ?Pagination $pagination, $expiration = 0)
- findOneBy(array $criteria, ?Order $order = null, array $with, $expiration = 0)
- findFirst($with)
- findLast($with)
- save(EntityInterface $entity, array $with, $relationExistsCheck = false)
- remove(EntityInterface $entity)

*Computools\\CLightORM\\Tools\\Order* object can be used to sort query result.

```
$repository->findBy([
        'name' => 'test'
    ],
    new Order('name', 'DESC')
)

```

*expiration* parameter can be used to store search result to cache. If isn't equals 0 than first call result will be stored to cache. Then method call will return data from cache, until expires. For detailed description see *Cache* part.

*With* parameter provides you possibility to include related entities into result. You may also get related entities of related entity etc. For example:

```
$book = $bookRepository->findLast(['themes', 'authors']);

```

This will find last book with related themes and authors (you must specify entity field name, that corresponds to relation)

```
$book = $bookRepository->findLast(
    [
        'themes' => [
            'posts'
        ],
        'authors'
    ]
);

```

This will find last book with themes and authors. Besides, related posts will be found for all the themes. For save method, you also may define $with parameter, to get related entities in result.

Nesting level is not limited, so you can use constructions like this:

```
 $book = $bookRepository->findLast(
        [
            'themes' => [
                'posts' => [
                    'editors' => [
                        'userProfile'
                    ]
                ]
            ],
            'authors'
        ]
    );

```

First argument for repository's 'save' method takes a link to object, so you may not use method result to overwrite object variable.

```
$post = new Post();
$post->setUser($user);
$postRepository->save($post);
return $post;

```

But, of course, you can use return value:

```
$post = new Post();
$post->setUser($user);
return $postRepository->save($post);

```

If there is a collection given as repository result, that would be an array of entities.

You can use Computools\\CLightORM\\Tools\\Pagination as third parameter for findBy to paginate result.

```
$posts = $repository->findByUser($this->getUser(), ['theme'], (new Pagination())->setPagination(1, 20));

```

Or

```
$posts = $repository->findByUser($this->getUser(), ['theme'], (new Pagination())->setLimitOffset(20, 0));

```

You can also use **orm** object inside the repository class to make some custom queries.

Query
-----

[](#query)

You can use built-in queries objects to do some custom logic.

CLightORM object can create any type of queries. This object is accessable inside any repository:

```
class PostRepository extends AstractRepository
{
    public function getEntityClass(): string
    {
        return Post::class;
    }

    public function findPostsCustom()
    {
        $query = $this->orm->createQuery();

        $query
            ->select('id, name')
            ->from($this->table)
            ->where('title', 'test')
            ->where('type', 'test')
            ->whereExpr('id < 5')
            ->whereExpr('id > 2')
            ->whereArray([
                'title' => 'test',
                'type' => 'test'
            ])
            ->groupBy('id')
            ->order('id', 'DESC')
            ->limit(10, 5)
            ->execute();

        return $query->getResult();
    }
}

```

Method above demonstrates possible methods for query. It returns array as result. If you want to map result to some entity, you must not specify select fields, and call *mapToEntity* or *mapToEntities* method:

```
$query
    ->from($this->table);
    ->whereExpr('id < 5')
    ->whereExpr('id > 2')
    ->execute();
return $this->mapToEntities($query, ['author', 'editor']);

```

To use JOIN command, you can use Computools\\CLightORM\\Database\\Query\\Structure\\Join. Constructor arguments are:

- string $type (LEFT, RIGHT, INNER)
- string $table (table name)
- string $condition (on p.user\_id = u.id for example)
- string $alias = null

    $query -&gt;from('post', 'p') -&gt;join(new Join('INNER', 'user', 'ON p.author\_id = u.id', 'u')) -&gt;where('p.id', 5) -&gt;execute()

**Many-to-Many** relations saving can do checks for already existed relations. So if you want relations to not duplicate, you can provide third parameter as **true**:

```
$post = $postRepository->find(1);
$user = $userRepository->find(1);

$post->addRelation($user);
$postRepository->save($post, [], true);

```

This call will also call duplicates check and just will not add same relation. If you provide third argument as false, than check will not be executed, and will throw exception if database table has unique indexes for relations.

Cache
-----

[](#cache)

Cache mechanism can be used to store some search results. To use it, you need to specify cache type while creating CLightORM instance. There is two different options to store results - memcached and filesystem.

*Computools\\CLightORM\\Cache\\Memcache* takes two parameters:

- host(string) - memcached server host, default is 'localhost',
- port(int) - memcached server port, default is '11211'

*Computools\\CLightORM\\Cache\\Filecache* takes cache dir as parameter, default is 'cache'.

So, to use cache you need to write something like that:

```
$pdo = new \PDO(
                sprintf(
                    '%s:host=%s;port=%s;dbname=%s',
                    'mysql',
                    '127.0.0.1',
                    '3306',
                    'test'
                ),
            'user',
            'password'
            );

$clightORM = new CLightORM($pdo, new Filecache('response/cache'));

```

Or

```
$clightORM = new CLightORM($pdo, new Memcache('localhost', 11211));

```

Than all your repos will be created with cache as private property. You can provide *expiration* parameter for findBy etc.

```
$repository->findBy(array $criteria, null, array $with = [], null, $expiration = 3600)

```

If expiration = 0, than cache will not be used. If not - data will be taken from cache if not expired yet.

###  Health Score

27

—

LowBetter than 47% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

31

Last Release

2743d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/799e23b2f174a092170256929ab120bb572ecd53bdb28fca68a0f23b3e69a5c6?d=identicon)[e.martynov](/maintainers/e.martynov)

---

Top Contributors

[![eugeniy-martynov](https://avatars.githubusercontent.com/u/38651479?v=4)](https://github.com/eugeniy-martynov "eugeniy-martynov (48 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/computools-clight-orm/health.svg)

```
[![Health](https://phpackages.com/badges/computools-clight-orm/health.svg)](https://phpackages.com/packages/computools-clight-orm)
```

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k117.2M114](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[jfelder/oracledb

Oracle DB driver for Laravel

11518.4k](/packages/jfelder-oracledb)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
