PHPackages                             centamiv/concrete - 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. centamiv/concrete

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

centamiv/concrete
=================

A simple and solid ORM for PHP applications.

20[3 issues](https://github.com/centamiv/concrete/issues)PHP

Since Dec 26Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/centamiv/concrete)[ Packagist](https://packagist.org/packages/centamiv/concrete)[ RSS](/packages/centamiv-concrete/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Concrete ORM
============

[](#concrete-orm)

**Concrete** is a simple and solid ORM for PHP applications. It provides an elegant Active Record implementation and a fluent Query Builder to interact with your database.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require centamiv/concrete
```

Configuration
-------------

[](#configuration)

To start using Concrete, you need to initialize the database connection. Typically, you would do this in your application's bootstrap file (e.g., `index.php`).

### MySQL

[](#mysql)

```
use Concrete\Database;
use Concrete\Connection\MysqlDriver;

require 'vendor/autoload.php';

// Initialize the database connection
Database::init(
    new MysqlDriver(),
    '127.0.0.1', // Host
    'my_database', // Database Name
    'root',      // User
    'password'   // Password
);
```

### SQLite

[](#sqlite)

```
use Concrete\Database;
use Concrete\Connection\SqliteDriver;

require 'vendor/autoload.php';

// Initialize the database connection
// For SQLite, the second parameter is the database file path
Database::init(
    new SqliteDriver(),
    '/path/to/database.sqlite', // Database file path (or ':memory:' for in-memory)
);
```

### PostgreSQL

[](#postgresql)

```
use Concrete\Database;
use Concrete\Connection\PostgresDriver;

require 'vendor/autoload.php';

// Initialize the database connection
Database::init(
    new PostgresDriver(),
    '127.0.0.1',     // Host
    'my_database',   // Database Name
    'postgres',      // User
    'password'       // Password
);
```

### SQL Server

[](#sql-server)

```
use Concrete\Database;
use Concrete\Connection\SqlServerDriver;

require 'vendor/autoload.php';

// Initialize the database connection
Database::init(
    new SqlServerDriver(),
    'localhost',     // Host (Server)
    'my_database',   // Database Name
    'sa',            // User
    'password'       // Password
);
```

Usage
-----

[](#usage)

### Defining Models

[](#defining-models)

Create a model class that extends `Concrete\Model`. You need to define the `TABLE` constant. By default, the primary key is assumed to be `id`.

```
namespace App\Models;

use Concrete\Model;

class User extends Model
{
    public const TABLE = 'users';

    public const COL_ID = 'id';
    public const COL_NAME = 'name';
    public const COL_EMAIL = 'email';
    public const COL_AGE = 'age';
    public const COL_ACTIVE = 'active';
    public const COL_ROLE_ID = 'role_id';
    public const COL_CREATED_AT = 'created_at';
}
```

#### Custom Primary Keys

[](#custom-primary-keys)

If your table uses a primary key other than `id`, you can override the `PRIMARY_KEY` constant. Concrete also supports **composite primary keys**.

```
class Order extends Model
{
    public const TABLE = 'orders';

    // Simple Primary Key
    public const PRIMARY_KEY = 'id';
}

class OrderItem extends Model
{
    public const TABLE = 'order_items';

    // Composite Primary Key
    public const PRIMARY_KEY = ['order_id', 'product_id'];
}
```

### Basic CRUD

[](#basic-crud)

#### Creating Records

[](#creating-records)

To create a new record, instantiate your model, set attributes, and call `save()`.

```
$user = new User();
$user->set(User::COL_NAME, 'Mario Rossi')
     ->set(User::COL_EMAIL, 'mario@example.com')
     ->save();

// Access the auto-incremented ID (if applicable)
echo $user->get(User::COL_ID);
```

#### Retrieving Records

[](#retrieving-records)

Use the `find()` static method to retrieve a record by its primary key.

```
// Find by single primary key
$user = User::find(1);

if ($user) {
    echo $user->get(User::COL_NAME);
}

// Find by composite primary key
$item = OrderItem::find(['order_id' => 10, 'product_id' => 5]);
```

#### Updating Records

[](#updating-records)

Retrieve a record, modify its attributes, and call `save()` again.

```
$user = User::find(1);
$user->set(User::COL_EMAIL, 'new_email@example.com');
$user->save();
```

#### Deleting Records

[](#deleting-records)

Retrieve a record and call `delete()`.

```
$user = User::find(1);
if ($user) {
    $user->delete();
}
```

### Query Builder

[](#query-builder)

Concrete provides a fluent Query Builder for more complex queries. You can access it via the `query()` static method on your models.

#### Filtering (`where`)

[](#filtering-where)

```
$users = User::query()
    ->where(User::col(User::COL_ACTIVE), '=', 1)
    ->where(User::col(User::COL_AGE), '>', 18)
    ->get();

foreach ($users as $user) {
    echo $user->get(User::COL_NAME);
}
```

#### Ordering (`orderBy`)

[](#ordering-orderby)

```
$users = User::query()
    ->where(User::col(User::COL_ACTIVE), '=', 1)
    ->orderBy(User::col(User::COL_CREATED_AT), 'DESC')
    ->get();
```

#### Joins (`join`, `leftJoin`)

[](#joins-join-leftjoin)

You can join other tables using the `join` or `leftJoin` methods.

```
// Assuming Role model exists with constants
$users = User::query()
    ->select(User::col('*'), Role::colAs(Role::COL_NAME, 'role_name'))
    ->join(Role::TABLE, User::col(User::COL_ROLE_ID), '=', Role::col(Role::COL_ID))
    ->get();
```

You can also use `rightJoin`:

```
$users = User::query()
    ->rightJoin(Role::TABLE, User::col(User::COL_ROLE_ID), '=', Role::col(Role::COL_ID))
    ->get();
```

#### Updating Records (`update`)

[](#updating-records-update)

```
$affected = User::query()
    ->where(User::col(User::COL_ACTIVE), '=', 0)
    ->update([User::col(User::COL_ACTIVE) => 1]);
```

#### Deleting Records (`delete`)

[](#deleting-records-delete)

```
$deleted = User::query()
    ->where(User::col(User::COL_AGE), 'where(User::col(User::COL_ACTIVE), '=', 1)
            ->get();

        return view('users.index', ['users' => $users]);
    }
}
```

License
-------

[](#license)

This library is open-sourced software licensed under the MIT license.

###  Health Score

14

—

LowBetter than 2% of packages

Maintenance31

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity14

Early-stage or recently created project

 Bus Factor1

Top contributor holds 57.1% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/4bb6e94628f1de489fb3f7114991eef0c4d84f8b42d507cadc2bd54fefc75091?d=identicon)[centamiv](/maintainers/centamiv)

---

Top Contributors

[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (4 commits)")[![centamiv](https://avatars.githubusercontent.com/u/4162703?v=4)](https://github.com/centamiv "centamiv (3 commits)")

### Embed Badge

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

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

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

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

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90440.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)[wildside/userstamps

Laravel Userstamps provides an Eloquent trait which automatically maintains `created\_by` and `updated\_by` columns on your model, populated by the currently authenticated user in your application.

7511.7M13](/packages/wildside-userstamps)

PHPackages © 2026

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