PHPackages                             picorm/picorm - 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. picorm/picorm

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

picorm/picorm
=============

Lightweight ORM

0.0.7(10y ago)204529[1 issues](https://github.com/iNem0o/PicORM/issues)[2 PRs](https://github.com/iNem0o/PicORM/pulls)1LGPLPHPPHP &gt;=5.4.0

Since Sep 4Pushed 6y ago7 watchersCompare

[ Source](https://github.com/iNem0o/PicORM)[ Packagist](https://packagist.org/packages/picorm/picorm)[ Docs](https://github.com/iNem0o/PicORM)[ RSS](/packages/picorm-picorm/feed)WikiDiscussions master Synced 6d ago

READMEChangelog (6)DependenciesVersions (9)Used By (1)

[![PicORM](/examples/picorm.png?raw=true "PicORM")](/examples/picorm.png?raw=true)

a lightweight PHP ORM.
======================

[](#a-lightweight-php-orm)

PicORM will help you to map your MySQL database rows into PHP object and create relations between them.
PicORM is an Active Record pattern implementation easy to install and use.

[![Build Status](https://camo.githubusercontent.com/c959713342e3c29134a248357a2865b0aeba4bd31166b582aeac8a34db7343c1/687474703a2f2f7472617669732d63692e6f72672f694e656d306f2f5069634f524d2e706e67)](http://travis-ci.org/iNem0o/PicORM)[![Latest Stable Version](https://camo.githubusercontent.com/2c637efd228e677120df291f9f10bab9e93d1a1d79a63ed7b34b066c517c11c0/68747470733a2f2f706f7365722e707567782e6f72672f7069636f726d2f7069636f726d2f76657273696f6e2e706e67)](https://packagist.org/packages/picorm/picorm)[![Total Downloads](https://camo.githubusercontent.com/2682e4e04a517bc7ba8fe0cc2e7ee23003af1218e8bf263ef48c3e7a0ab5d86f/68747470733a2f2f706f7365722e707567782e6f72672f7069636f726d2f7069636f726d2f646f776e6c6f6164732e706e67)](https://packagist.org/packages/picorm/picorm)

### Some stuff you need to know

[](#some-stuff-you-need-to-know)

- You can't have multiple primary key yet
- You can't use Many To Many relations with data in relation table yet
- Fork and pull request are encouraged!

### Install

[](#install)

**From composer**

Install composer in your www folder with `curl -sS https://getcomposer.org/installer | php`

Create a `composer.json` file with

```
{
    "require": {
        "picorm/picorm": "0.0.6"
    }
}
```

Install PicORM with `php composer.phar install`

**From source**
Clone `https://github.com/iNem0o/PicORM` repository and include `PicORM` autoload with

```
    require('path/to/PicORM/src/autoload.inc.php');
```

**Load and configure PicORM**
Before using `PicORM` you have to configure it. `datasource` is the only required parameter and have to be a PDO instance

```
\PicORM\PicORM::configure(array(
	'datasource' => new PDO('mysql:dbname=DBNAME;host=HOST', 'DBLOGIN', 'DBPASSWD')
));
```

Model
-----

[](#model)

**Implements a Model**
First you have to create a table, which your model will be mapped to

```
    CREATE TABLE `brands` (
      `idBrand` int(11) NOT NULL AUTO_INCREMENT,
      `nameBrand` varchar(100) NOT NULL,
      `noteBrand` float DEFAULT 0,
      PRIMARY KEY (`idBrand`)
    ) ENGINE=MyISAM;
```

Next create a class which extends `\PicORM\Model`You have to implements some static parameters to describe your MySQL table schema, if you forgot one of them, a `\PicORM\Exception` will remind you

*Required*
`protected static $_tableName` MySQL table name
`protected static $_primaryKey` table primary key field name
`protected static $_tableFields` array with all mysql table fields name without primary key

*Optional*
`protected static $_databaseName` name of the database if different from datasource main DB

and then, add one public property by table field with `public $fieldName`

**Brand model declaration**

```
    class Brand extends \PicORM\Model
    {
        protected static $_tableName = 'brands';
        protected static $_primaryKey = 'idBrand';

        protected static $_tableFields = array(
            'nameBrand',
            'noteBrand'
        );

        public $idBrand;
        public $nameBrand;
        public $noteBrand;

    }
```

**Create and save**

```
// creating new model
	$brand = new Brand();

// setting field
	$brand -> nameBrand = 'Peugeot';

// save model
	$brand -> save();
```

**Update and delete**

```
// Criteria with exact value (idBrand=10)
    $brand = Brand :: findOne(array('idBrand' => 10));

// setting model property
	$brand -> nameBrand = 'Audi';

// save model
	$brand -> save();

// save model
	$brand -> delete();
```

find() and findOne()
--------------------

[](#find-and-findone)

Every subclass of `Model` inherit of static methods `find()` and `findOne()`.
Theses methods are used to hydrate models from database rows.

```
/**
 * Find one model from criteria, allowing to order
 * @param array $where - associative
 * @param array $order - associative array
 */
public static function findOne($where = array(), $order = array())

/**
 * Return Collection instance from criteria, allowing to order and limit result
 * @param array $where - associative array
 * @param array $order - associative array
 * @param int $limitStart - int
 * @param int $limitEnd - int
 * @return Collection
 */
public static function find($where = array(),$order = array(), $limitStart = null, $limitEnd = null)
```

**How to use $where parameter**
this parameter is data for building a WHERE mysql clause

```
// simple criteria
	$where = array('field' => 1);

// custom operator
	$where = array('field' => array('operator' => ' ''
	 )
```

Collections
-----------

[](#collections)

Collections in PicORM are created by `::find()` method, accessible statically on each `\PicORM\Model` subclass.
Once you have a fresh \\PicORM\\Collection instance, data is not fetched yet. Fetching is done only when you try to access data using one of these ways

### Collections usage

[](#collections-usage)

```
// php array access
	$firstResult = $collection[0];

// counting collection
	$nbResults = count($collection);

// using getter
	$firstResult = $collection->get(0);

// iterate over the collection
	foreach($collection as $model)

// or manual fetching / re-fetching
	$collection->fetch();
```

An \\PicORM\\Collection instance can execute UPDATE and DELETE queries on the collection members before fetching data, this way using `update()` or `delete()` method produce only one MySQL query based on `find()` restriction parameters.

```
// Delete all models in collection
    $collection = Brand::find(array('noteBrand' => 10))
                         -> delete();

// Update and set noteBrand = 5 to collection
    $collection = Brand::find(array('noteBrand' => array('IN(9,10,11)')))
                         -> update(array('noteBrand' => 5));

```

### Collections pagination

[](#collections-pagination)

Pagination in collection is based on MySQL FOUND\_ROWS(). Remembering that collection is not fetched until you use it, when you have a Collection instance, its easy to activate pagination with

```
$carCollection = Car::find();           // grab all car from database
$carCollection->activePagination(50);   // asking for 50 models by page
$carCollection->paginate(1);            // asking for first page
```

You have now access to 2 more methods.

```
$nbTotalPages = $carCollection -> getTotalPages();
$nbTotalModels = $carCollection -> foundModels();
```

### Collection advanced query

[](#collection-advanced-query)

You are able to alter the fetch query before it execution using the `getQueryHelper()` method on the collection. You will get an instance of `InternalQueryHelper` which you can manipulate. Once you are done, just set the collection query helper with `setQueryHelper($helper)`

That way you can load custom data inside a model instance.

```
$cars  = Car::find();
$queryBuilder = $cars->getQueryHelper();
$queryBuilder->select("COUNT(idTag) as nbTags");
$queryBuilder->leftJoin('car_has_tag cht', 'cht.idCar = cars.idCar');
$queryBuilder->groupBy("cars.idCar");
$cars->setQueryHelper($queryBuilder);
```

Relations between models
------------------------

[](#relations-between-models)

Using relations will need you to add a property and a method to your model subclass.
`protected static $_relations = array();` needed to be implemented to store model relations `protected static function defineRelations() { }` method to declare your relation

overriding `defineRelations()` in your subclass allow you to declare your model specific relations using one of the 3 next methods.

```
/**
 * Add a OneToOne relation
 * @param $sourceField          - model source field
 * @param $classRelation        - relation model classname
 * @param $targetField          - related model target field
 * @param array $autoGetFields  - field to auto get from relation when loading model
 * @param string $aliasRelation - override relation auto naming className with an alias
 *                                    (ex : for reflexive relation)
 */
protected static function addRelationOneToOne($sourceField, $classRelation, $targetField, $autoGetFields = array(), $aliasRelation = '')

/**
 * Add a OneToMany relation
 * @param $sourceField          - model source field
 * @param $classRelation        - relation model classname
 * @param $targetField          - related model target field
 * @param string $aliasRelation - override relation auto naming className with an alias
 */
protected static function addRelationOneToMany($sourceField, $classRelation, $targetField, $aliasRelation = '')

/**
 * Add a ManyToMany relation
 * @param $sourceField           - model source field
 * @param $classRelation         - relation model name
 * @param $targetField           - related model field
 * @param $relationTable         - mysql table containing the two models ID
 * @param string $aliasRelation  - override relation auto naming className
 */
protected static function addRelationManyToMany($sourceField, $classRelation, $targetField, $relationTable, $aliasRelation = '')
```

**Using relation**

This example will use the following MySQL schema

```
CREATE TABLE `brands` (
	`idBrand` int(11) NOT NULL AUTO_INCREMENT,
	`nameBrand` varchar(100) NOT NULL,
	`noteBrand` float DEFAULT 0,
PRIMARY KEY (`idBrand`)
) ENGINE=MyISAM;

CREATE TABLE  `cars` (
	`idCar` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`idBrand` INT NOT NULL,
	`nameCar` VARCHAR(100) NOT NULL
) ENGINE = MYISAM ;

CREATE TABLE `car_have_tag` (
	`idCar` INT NOT NULL,
	`idTag` INT NOT NULL,
PRIMARY KEY (`idCar`,`idTag`)
) ENGINE = MYISAM ;

CREATE TABLE `tags` (
	`idTag` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`libTag` VARCHAR(255) NOT NULL
) ENGINE = MYISAM ;
```

First you have to declare your 3 models and their relations

```
class Brand extends Model
{
	protected static $_tableName = 'brands';
	protected static $_primaryKey = "idBrand";
	protected static $_relations = array();

	protected static $_tableFields = array(
		'nameBrand',
		'noteBrand'
	);

	public $idBrand;
	public $nameBrand;
	public $noteBrand;

	protected static function defineRelations()
	{
		// create a relation between Brand and Car
		// based on this.idBrand = Car.idBrand
		self::addRelationOneToMany('idBrand', 'Car', 'idBrand');
	}
}

class Car extends Model
{
	protected static $_tableName = 'cars';
	protected static $_primaryKey = "idCar";
	protected static $_relations = array();

	protected static $_tableFields = array(
		'idBrand',
		'nameCar'
	);

	public $idCar;
	public $idBrand;
	public $nameCar = '';

	protected static function defineRelations()
	{
		// create a relation between Car and Brand
		// based on this.idBrand = Brand.idBrand
		// nameBrand is added to autoget fields which is automatically fetched
		// when model is loaded
		self::addRelationOneToOne('idBrand', 'Brand', 'idBrand', 'nameBrand');

		// create a relation between Car and Tag using a relation table car_have_tag
		self::addRelationManyToMany("idCar","Tag","idTag","car_have_tag");
	}
}

class Tag extends Model
{
	protected static $_tableName = 'tags';
	protected static $_primaryKey = "idTag";
	protected static $_relations = array();

	protected static $_tableFields = array(
		'libTag',
	);

	public $idTag;
	public $libTag = '';

	protected static function defineRelations()
	{
		// create a relation between Tag and Car using a relation table car_have_tag
		self::addRelationManyToMany('idTag','Car','idCar','car_have_tag');
	}
}
```

Now you can start to create and manipulates related models

```
// creating a brand
    $brand = new Brand();
    $brand -> nameBrand = "Peugeot";
    $brand -> save();

// creating a car
    $car = new Car();
    $car -> nameCar = "205 GTi";

// setting car's brand
    $car -> setBrand($brand);

// other way to setting car's brand
    $car -> idBrand = $brand -> idBrand;
    $car -> save();

// if we look for our car
    $car = Car :: findOne(array('nameCar' => '205 GTi'));

// we can get brand of the car
    $car -> getBrand();

// or we can access brand name directly because it has been added to relation auto get fields
    $car -> nameBrand;

```

As you declare a one to many relation from Brand to Car you can also using setter and getter on the other side

```
// get all cars from brand
// method return instance of \PicORM\Collection
    foreach($brand -> getCar() as $cars)

// get all cars from brand with custom criteria
// parameters are same as find() method
// method return instance of \PicORM\Collection
    $brand -> getCar($where,$order,$limitStart,$limitStop);
```

Many to many relations are easy to use too

```
// creating some tags
    $tag = new Tag();
    $tag -> libTag = 'tag 1';
    $tag -> save();

    $tag2 = new Tag();
    $tag2 -> libTag = 'tag 2';
    $tag2 -> save();

    $tag3 = new Tag();
    $tag3 -> libTag = 'tag 3';
    $tag3 -> save();

// setting car's tags
    $car -> setTag(array($tag,$tag2,$tag3));

// getting car's tags (return instance of \PicORM\Collection)
    $car -> getTag();

// getting car's tags with custom criteria
// parameters are same as find() method
// method return instance of \PicORM\Collection
    $car -> getTag($where,$order,$limitStart,$limitStop);

// unset relation between $car and $tag2
    $car -> unsetTag($tag2);
```

Changelog
---------

[](#changelog)

#### UNSTABLE 0.0.1

[](#unstable-001)

- Initial release

#### UNSTABLE 0.0.2

[](#unstable-002)

- Bug fixes
- Add namespace support and pdo fetch mode selection
- Add transaction support

#### BETA 0.0.3

[](#beta-003)

- Bug fixes
- Refactoring MySQL
- Collections
- Tests

#### BETA 0.0.4

[](#beta-004)

- Refactoring Entity to Model
- QueryBuilder : SQL hint and FoundRows
- Collection pagination
- Tests

#### BETA 0.0.5

[](#beta-005)

- Customize collection query builder
- Moving from SQL\_CALC\_FOUND\_ROWS to count(\*)
- Fix bug with relation alias name and caps
- Fix bug in relation getter with LIMIT clause
- Fix bug with no where / order / limit in many to many getter
- Refactoring Code
- Refactoring PHPDoc
- Refactoring Tests
- Adding TravisCI

#### BETA 0.0.6

[](#beta-006)

- Adding setter for database and table
- Bugfix:update query doesnt use tablename getter
- Bugfix : where value was not prefixed with table name in many to many getter
- Update readme

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 97.9% 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 ~131 days

Recently: every ~184 days

Total

7

Last Release

3852d ago

PHP version history (2 changes)0.0.1PHP &gt;=5.3.0

0.0.5PHP &gt;=5.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/a3f131b33e120f56f303f0f1d74c3adb10f2abbee8868f35a2b08310cd4c1161?d=identicon)[iNem0o](/maintainers/iNem0o)

---

Top Contributors

[![iNem0o](https://avatars.githubusercontent.com/u/1144755?v=4)](https://github.com/iNem0o "iNem0o (141 commits)")[![raphael-homann](https://avatars.githubusercontent.com/u/7700663?v=4)](https://github.com/raphael-homann "raphael-homann (3 commits)")

---

Tags

orm

### Embed Badge

![Health badge](/badges/picorm-picorm/health.svg)

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

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[doctrine/doctrine-bundle

Symfony DoctrineBundle

4.8k241.3M3.3k](/packages/doctrine-doctrine-bundle)[doctrine/persistence

The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.

4.1k286.5M762](/packages/doctrine-persistence)[gedmo/doctrine-extensions

Doctrine behavioral extensions

4.1k118.8M366](/packages/gedmo-doctrine-extensions)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[beberlei/doctrineextensions

A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL, Oracle, PostgreSQL and SQLite.

2.1k75.1M146](/packages/beberlei-doctrineextensions)

PHPackages © 2026

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