PHPackages                             struktal/struktal-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. struktal/struktal-orm

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

struktal/struktal-orm
=====================

PHP library implementing the DAO pattern for easier database handling

3.0.1(2mo ago)01.2k↓50%[3 issues](https://github.com/Struktal/struktal-orm/issues)3MITPHPPHP &gt;=8.2.0CI passing

Since Jun 17Pushed 2mo ago1 watchersCompare

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

READMEChangelog (10)Dependencies (1)Versions (16)Used By (3)

Struktal-ORM
============

[](#struktal-orm)

This is a PHP library that provides helpful classes and methods for working with objects that are stored in a database.

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

[](#installation)

To install this library, include it in your project using Composer:

```
composer require struktal/struktal-orm
```

Data access object (DAO) pattern
================================

[](#data-access-object-dao-pattern)

Using the data access object pattern allows you to easily access and manipulate data in a database with PHP objects.

There are so-called "model objects" that represent the data that's being stored in the database, and for each table there is an own model object.

There's also a data access object interface that defines the standard operations that can be performed on the model objects, such as creating, reading and updating entries. For every model object, there is an own belonging data access object.

Usage
=====

[](#usage)

Before you can use this library, you need to connect it to your database. You can do this in the startup of your application:

```
\struktal\ORM\Database::connect(
    $host,
    $database,
    $username,
    $password
);
```

Then, you can use the library's features in your code.

Inheriting from model and data access objects
---------------------------------------------

[](#inheriting-from-model-and-data-access-objects)

To prevent you from having to write the same code over and over again, there are classes called `GenericEntity` (model object) and `GenericEntityDAO` (data access object interface) that every custom object should extend from within the namespace `\struktal\ORM`. The `GenericEntity` class already implements the table columns

- `id` (integer) - The unique identifier of the object
- `created` (datetime) - The date and time when the object was created
- `updated` (datetime) - The date and time when the object was last updated

and the `GenericEntityDAO` the standard operations

- `save(GenericObject $object)` to upsert an object's database entry
- `delete(GenericObject $object)` to delete an object's database entry
- `getObject(...)` to get a single object from the database
- `getObjects(...)` to get multiple objects from the database

To set up a new object, you need to create a new class with the same name as the table in the database, and extend it from `\struktal\ORM\GenericEntity`. For example, if you have a table called `User`, you would create a class like this:

```
class User extends \struktal\ORM\GenericEntity {
    public string $username;
    public string $password;

    // Feel free to add getters, setters, and other methods as needed
}
```

Next, you'll also have to create a new DAO class that extends `\struktal\ORM\GenericEntityDAO`. The DAO's class name should be the same as the model object's class name, but with `DAO` appended to it. For the `User` model object, the DAO class would look like this:

```
class UserDAO extends \struktal\ORM\GenericEntityDAO {
    // Basic DAO methods already implemented in GenericEntityDAO
}
```

If you need methods with custom queries or other non-standard operations for this specific object, you can add them to this DAO class.

The above code allows to access and manipulate the database table called `User` with the following structure:

`id``username``password``created``updated``INT``VARCHAR``VARCHAR``DATETIME``DATETIME`Database tables have to be created manually. To do so, orientate yourself on this example:

```
CREATE TABLE IF NOT EXISTS `User` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(255) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `created` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updated` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```

Saving an object to the database
--------------------------------

[](#saving-an-object-to-the-database)

Once you have created the model and DAO classes, crating and updating an object is easy by using the DAO's `save()` method. It differs between inserting a new entry and updating an existing one by checking if the `id` attribute is set.

```
$user = new User();
$user->username = "JohnDoe";
$user->password = "SecurePassword123"; // Make sure to hash passwords before saving them!

User::dao()->save($user); // Inserts a new entry into the database

$user->password = "NewSecurePassword456"; // Update the password
User::dao()->save($user); // Updates the existing entry in the database
```

The `save()` method will automatically set the `id`, `created`, and `updated` attributes of the object if a new database entry was inserted.

Loading objects from the database
---------------------------------

[](#loading-objects-from-the-database)

To load objects from the database, you can use the DAO's `getObject()` and `getObjects()` methods:

```
// Get a single object by its ID
$user = User::dao()->getObject([
    "id" => 1
]);

// Get all objects
$users = User::dao()->getObjects();
```

For both methods, you can set the following parameters:

- `filters`: An associative array that contains requirements for the objects that should be returned with the column name as key and the value that the column should have as value
- `orderBy`: A column name that the returned objects should be ordered by
- `orderAsc`: A boolean that indicates whether the objects should be ordered ascending (default) or descending
- `limit`: An integer that limits the number of returned objects (-1 for no limit)
- `offset`: An integer that sets the offset for the returned objects

You can also write more detailed queries by using complex `DAOFilter`s. They allow you to use other operators than the default `=` operator. Use it as follows:

```
$users = User::dao()->getObjects([
    new \struktal\ORM\DAOFilter(
        \struktal\ORM\DAOFilterType::LIKE,
        "username",
        "John%"
    ),
    new \struktal\ORM\DAOFilter(
        \struktal\ORM\DAOFilterType::GREATER_THAN,
        "id",
        10
    )
]);
```

This example will return all users whose username starts with "John" and whose ID is greater than 10.

Deleting an object from the database
------------------------------------

[](#deleting-an-object-from-the-database)

To delete an object from the database, you can use the DAO's `delete()` method:

```
$user = User::dao()->getObject([
    "id" => 1
]);
User::dao()->delete($user);
```

Database evolutions
-------------------

[](#database-evolutions)

This library also provides a way to initialize the database and perform migrations. To do so, create a directory in your project where you want to store the `.sql` files that define your database schema. Then, execute the evolution script:

```
php vendor/bin/evolve --config-loader PATH_TO_CONFIG_LOADER --evolutions-directory PATH_TO_EVOLUTIONS_DIRECTORY
```

with `PATH_TO_CONFIG_LOADER` being the path to a PHP file that sets up the database connection and `PATH_TO_EVOLUTIONS_DIRECTORY` being the path to the directory where you store the `.sql` files. The script will then execute all `.sql` files in the evolutions directory in alphabetical order and keep track of which files have already been executed.

To create an initial setup for the database, create a file named, for example, `00000000-tables.sql`, and then, to adjust the database schema when implementing new features, you can create files prefixed with the current date, and then a short description of the implemented feature.

Dependencies
============

[](#dependencies)

This library uses the following dependencies:

- **ext-pdo**
- **pest** - GitHub: [pestphp/pest](https://github.com/pestphp/pest), licensed under [MIT license](https://github.com/pestphp/pest/blob/3.x/LICENSE.md)

License
=======

[](#license)

This software is licensed under the MIT license. See the [LICENSE](LICENSE) file for more information.

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance83

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity57

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 ~19 days

Recently: every ~40 days

Total

14

Last Release

87d ago

Major Versions

1.0.3 → 2.0.02025-09-11

2.4.4 → 3.0.02026-02-20

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/49905418?v=4)[Jens Ostertag](/maintainers/JensOstertag)[@JensOstertag](https://github.com/JensOstertag)

---

Top Contributors

[![JensOstertag](https://avatars.githubusercontent.com/u/49905418?v=4)](https://github.com/JensOstertag "JensOstertag (44 commits)")

---

Tags

databaseobjects

###  Code Quality

TestsPest

### Embed Badge

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

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

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k578.4M5.6k](/packages/doctrine-dbal)[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/migrations

PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.

4.8k204.8M440](/packages/doctrine-migrations)[doctrine/data-fixtures

Data Fixtures for all Doctrine Object Managers

2.9k136.1M516](/packages/doctrine-data-fixtures)[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k46.2M405](/packages/robmorgan-phinx)

PHPackages © 2026

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