PHPackages                             smoren/containers-transactional - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. smoren/containers-transactional

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

smoren/containers-transactional
===============================

Abstract transactional containers and data structures

v0.1.3(4y ago)020MITPHPPHP &gt;=7.4

Since Dec 23Pushed 4y ago2 watchersCompare

[ Source](https://github.com/Smoren/containers-transactional-php)[ Packagist](https://packagist.org/packages/smoren/containers-transactional)[ RSS](/packages/smoren-containers-transactional/feed)WikiDiscussions master Synced 4w ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (0)

Transactional containers and data structures
============================================

[](#transactional-containers-and-data-structures)

Abstract wrapper structure for providing transactional interface for editing objects.

Includes implementations of transactional wrappers for some data containers and structures.

### How to install as dependency to your project

[](#how-to-install-as-dependency-to-your-project)

```
composer require smoren/containers-transactional

```

### Unit testing

[](#unit-testing)

```
composer install
./vendor/bin/codecept build
./vendor/bin/codecept run unit tests/unit

```

### Using with your class

[](#using-with-your-class)

#### Class definitions

[](#class-definitions)

```
use Smoren\Containers\Transactional\Base\TransactionWrapper;
use Smoren\Containers\Transactional\Base\Validator;
use Smoren\Containers\Transactional\Interfaces\ValidationRuleInterface;

/**
 * Your class that you want to wrap with transactional interface
 */
class YourClass {
    /**
     * Example attribute
     * @var int
     */
    public $someAttribute = 1;
    // ...
}

/**
 * @see Smoren\Containers\Transactional\Structs\TLinkedList
 */
class TYourClass extends TransactionWrapper
{
    /**
     * This overriding is needed only to specify method's return type
     * @inheritDoc
     */
    public function getWrapped(): YourClass
    {
        return parent::getWrapped();
    }

    /**
     * Unnecessary override if there is not default value of YourClass
     * @inheritDoc
     */
    protected function getDefaultWrapped()
    {
        return new YourClass();
    }

    /**
     * @inheritDoc
     * @return string
     */
    protected function getWrappedType(): ?string
    {
        return YourClass::class;
    }

    /**
     * Unnecessary override if you are not going to use validation
     * @inheritDoc
     * @return Validator
     * @throws \Smoren\ExtendedExceptions\LogicException
     */
    protected function getDefaultValidator(): ?Validator
    {
        return (new Validator())
            ->addRule('validation_rule_alias', MyValidationRule::class);
    }
}

/**
 * This declaration is not necessary if you are not going to use validation
 * @see Smoren\Containers\Transactional\Tests\Unit\Utility\PositiveNumberValidationRule
 */
class MyValidationRule implements ValidationRuleInterface
{
    protected array $errors = [];

    /**
     * @inheritDoc
     */
    public function validate($data, $owner): bool
    {
        // ...
        return true;
    }

    /**
     * @inheritDoc
     */
    public function getErrors()
    {
        return $this->errors;
    }
}
```

#### Client code

[](#client-code)

```
use Smoren\Containers\Transactional\Exceptions\ValidationException;

$yourObject = new YourClass();
$tWrapper = new TYourClass($yourObject);

echo $yourObject->someAttribute; // output: 1
echo $tWrapper->getWrapped()->someAttribute; // output: 1

$tWrapper->interact(function(YourClass $tmpObjectState) {
    $tmpObjectState->someAttribute = 2;
});

echo $yourObject->someAttribute; // output: 1

try {
    $tWrapper->validate(); // validate only
    echo $yourObject->someAttribute; // output: 1
} catch(ValidationException $e) {
    print_r($e->getErrors()); // output: ['validation_rule_alias' => [...]]
}

try {
    $tWrapper->apply(); // validate and apply
    echo $yourObject->someAttribute; // output: 2
} catch(ValidationException $e) {
    print_r($e->getErrors()); // output: ['validation_rule_alias' => [...]]
}
```

### Ready to use transactional containers

[](#ready-to-use-transactional-containers)

#### TArray

[](#tarray)

Wraps PHP array with transactional interface.

```
use Smoren\Containers\Transactional\Structs\TArray;
use Smoren\Containers\Transactional\Exceptions\ValidationException;

$ta = new TArray([1, 2, 3]);
print_r($ta->getWrapped()); // output: [1, 2, 3]

$ta->interact(function(array &$arr) {
    array_push($arr, 4);
    array_push($arr, 5);
    $arr[0] = 0;
});

try {
    print_r($ta->getWrapped()); // output: [1, 2, 3]
    $ta->apply();
    print_r($ta->getWrapped()); // output: [0, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}
```

#### TLinkedList

[](#tlinkedlist)

Classic implementation of linked list data structure wrapped with transactional interface.

Wraps [LinkedList](https://github.com/Smoren/structs-php#linkedlist) container.

```
use Smoren\Containers\Transactional\Structs\TLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\LinkedList;

$tll = new TLinkedList([1, 2, 3]);
print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3]

$tll->interact(function(LinkedList $list) {
    $list->pushBack(4);
    $list->pushBack(5);
});

try {
    print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3]
    $tll->apply();
    print_r($tll->getWrapped()->toArray()); // output: [1, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}
```

#### TMappedCollection

[](#tmappedcollection)

Map-like data structure with transactional interface.

Wraps [MappedCollection](https://github.com/Smoren/structs-php#mappedcollection) container.

```
use Smoren\Containers\Transactional\Structs\TMappedCollection;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\MappedCollection;

$tmc = new TMappedCollection([
    '0' => ['id' => 0],
]);

print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0]]

$tmc->interact(function(MappedCollection $collection) {
    $collection
        ->add('1', ['id' => 1])
        ->add('2', ['id' => 2])
        ->delete('2');
});

try {
    print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0]]
    $tmc->apply();
    print_r($tmc->getWrapped()->toArray()); // output: ['0' => ['id' => 0], ['1' => ['id' => 1]]]
} catch(ValidationException $e) {
    // if validation failed
}
```

#### TMappedLinkedList

[](#tmappedlinkedlist)

LinkedList with mapping by id and with transactional interface.

Wraps [MappedLinkedList](https://github.com/Smoren/structs-php#mappedlinkedlist) container.

```
use Smoren\Containers\Transactional\Structs\TMappedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\MappedLinkedList;

$tmll = new TMappedLinkedList(
    new MappedLinkedList([1 => 11])
);

print_r($tmll->getWrapped()->toArray()); // output: [1 => 11]

$tmll->interact(function(MappedLinkedList $list) {
    $list->pushBack(2, 22);
    $list->pushBack(3, 33);
});

try {
    print_r($tmll->getWrapped()->toArray()); // output: [1 => 11]
    $tmll->apply();
    print_r($tmll->getWrapped()->toArray()); // output: [1 => 11, 2 => 22, 3 => 33]
} catch(ValidationException $e) {
    // if validation failed
}
```

#### TSortedLinkedList

[](#tsortedlinkedlist)

LinkedList with presort and transactional interface.

Wraps [SortedLinkedList](https://github.com/Smoren/structs-php#sortedlinkedlist) container.

```
use Smoren\Containers\Transactional\Structs\TSortedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\SortedLinkedList;

/**
 * Class IntegerSortedLinkedList
 */
class IntegerSortedLinkedList extends SortedLinkedList
{
    /**
     * @inheritDoc
     */
    protected function getComparator(): callable
    {
        return function(int $lhs, int $rhs) {
            return $lhs > $rhs;
        };
    }
}

$tsll = new TSortedLinkedList(
    new IntegerSortedLinkedList([4, 1, 2])
);

print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 4]

$tsll->interact(function(IntegerSortedLinkedList $list) {
    $list->insert(5);
    $list->insert(3);
});

try {
    print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 4]
    $tsll->apply();
    print_r($tsll->getWrapped()->toArray()); // output: [1, 2, 3, 4, 5]
} catch(ValidationException $e) {
    // if validation failed
}
```

#### TSortedMappedLinkedList

[](#tsortedmappedlinkedlist)

LinkedList with presort, mapping and transactional interface.

Wraps [SortedMappedLinkedList](https://github.com/Smoren/structs-php#sortedmappedlinkedlist) container.

```
use Smoren\Containers\Transactional\Structs\TSortedMappedLinkedList;
use Smoren\Containers\Transactional\Exceptions\ValidationException;
use Smoren\Containers\Structs\SortedMappedLinkedList;

$tsmll = new TSortedMappedLinkedList(
    new SortedMappedLinkedList([2 => -2, 1 => -1, 4 => -4])
);

print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 4 => -4]

$tsmll->interact(function(SortedMappedLinkedList $list) {
    $list->insert(3, 0);
});

try {
    print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 4 => -4]
    $tsmll->apply();
    print_r($tsmll->getWrapped()->toArray()); // output: [1 => -1, 2 => -2, 3 => 0, 4 => -4]
} catch(ValidationException $e) {
    // if validation failed
}
```

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity40

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

Total

2

Last Release

1598d ago

### Community

Maintainers

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

---

Top Contributors

[![Smoren](https://avatars.githubusercontent.com/u/7403235?v=4)](https://github.com/Smoren "Smoren (26 commits)")

---

Tags

data-containersphp-librarytransactionalcollectionabstracttransactionStructurescontainers

###  Code Quality

TestsCodeception

### Embed Badge

![Health badge](/badges/smoren-containers-transactional/health.svg)

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

###  Alternatives

[phpcollection/phpcollection

General-Purpose Collection Library for PHP

1.0k64.0M34](/packages/phpcollection-phpcollection)[aimeos/map

Easy and elegant handling of PHP arrays as array-like collection objects similar to jQuery and Laravel Collections

4.2k412.9k11](/packages/aimeos-map)[league/period

Time range API for PHP

7335.4M21](/packages/league-period)[loophp/collection

A (memory) friendly, easy, lazy and modular collection class.

745663.8k13](/packages/loophp-collection)[athari/yalinqo

YaLinqo, a LINQ-to-objects library for PHP

4561.2M5](/packages/athari-yalinqo)[lorisleiva/lody

Load files and classes as lazy collections in Laravel.

956.6M9](/packages/lorisleiva-lody)

PHPackages © 2026

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