PHPackages                             frootbox/db - 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. frootbox/db

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

frootbox/db
===========

Frootbox Database Abstraction Layer

1.9.1(1mo ago)03.2k1GPL-3.0-or-laterPHPPHP &gt;=8.0

Since Jul 1Pushed 1mo agoCompare

[ Source](https://github.com/Frootbox/Db)[ Packagist](https://packagist.org/packages/frootbox/db)[ RSS](/packages/frootbox-db/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (1)Versions (34)Used By (1)

Frootbox Db
===========

[](#frootbox-db)

Frootbox Db is a small PHP database abstraction and Active Record layer for MySQL. It wraps `PDO`, provides a lightweight query builder, maps result rows to row objects, and offers a migration path from dynamic Active Record accessors to explicit getter and setter methods.

The package is intentionally compact. It is useful when you want simple models and rows without adopting a full ORM.

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

[](#installation)

Install the package with Composer:

```
composer require frootbox/db
```

Requirements:

- PHP 8.0 or newer
- `ext-pdo`
- MySQL or MariaDB when using the bundled MySQL adapter

Creating A Connection
---------------------

[](#creating-a-connection)

Create a DBMS adapter and wrap it in `Frootbox\Db\Db`:

```
use Frootbox\Db\Db;
use Frootbox\Db\Dbms\Mysql;

$db = new Db(new Mysql(
    host: 'localhost',
    schema: 'app',
    user: 'app',
    password: 'secret',
));
```

`Db` exposes low-level methods such as `query()`, `prepare()`, `fetch()`, `update()`, `delete()`, and transaction helpers.

Rows
----

[](#rows)

A row represents one database record. Extend `Frootbox\Db\Row` for your entities:

```
namespace App\Persistence;

use Frootbox\Db\Row;

class Page extends Row
{
    protected $table = 'pages';
    protected $model = Pages::class;

    public function getTitle(): ?string
    {
        return $this->getAttribute('title');
    }

    public function setTitle(?string $title): static
    {
        return $this->setAttribute('title', $title);
    }

    public function isVisible(): bool
    {
        return !empty($this->getAttribute('isVisible'));
    }
}
```

Rows store their raw database values internally and track changed attributes. Call `save()` to persist changed values and `delete()` to remove the record.

```
$page->setTitle('About us');
$page->save();
```

### Legacy Dynamic Accessors

[](#legacy-dynamic-accessors)

Older projects can still call accessors that are not explicitly defined:

```
$page->getTitle();
$page->setTitle('About us');
$page->isVisible();
```

These calls are handled by `Row::__call()` for backward compatibility. New code should add explicit methods that delegate to `getAttribute()` and `setAttribute()`. Deprecated dynamic calls are logged once per call site by default.

Disable that logging when needed:

```
\Frootbox\Db\Row::setDeprecatedMagicCallLogging(false);
```

Models
------

[](#models)

A model acts as a repository for one table:

```
namespace App\Persistence;

use Frootbox\Db\Model;

class Pages extends Model
{
    protected string $table = 'pages';
    protected string $class = Page::class;
}
```

Fetch rows:

```
$pages = new Pages($db);

$result = $pages->fetch([
    'where' => [
        'isVisible' => 1,
    ],
    'order' => [
        'title ASC',
    ],
]);

foreach ($result as $page) {
    echo $page->getTitle();
}
```

Fetch one row:

```
$page = $pages->fetchById(42);
$latest = $pages->fetchOne([
    'order' => ['date DESC'],
]);
```

Insert a row:

```
$page = new Page([
    'title' => 'About us',
    'isVisible' => 1,
]);

$pages->persist($page);
```

`insert()` is still available as a deprecated alias for `persist()`.

Conditions
----------

[](#conditions)

Condition objects can be used in `where` arrays for comparisons beyond equality:

```
use Frootbox\Db\Conditions\Greater;
use Frootbox\Db\Conditions\Like;

$result = $pages->fetch([
    'where' => [
        new Greater('id', 10),
        new Like('title', '%About%'),
    ],
]);
```

Available conditions include:

- `Equal`
- `NotEqual`
- `Greater`
- `GreaterOrEqual`
- `Less`
- `LessOrEqual`
- `Like`
- `IsNull`
- `IsNotNull`
- `InArray`
- `NotInArray`
- `MatchColumn`

Results
-------

[](#results)

`Frootbox\Db\Result` is an iterator, `Countable`, and `JsonSerializable`. It lazily converts raw database records into row objects while iterating.

Useful helpers:

```
$result->getCount();
$result->isEmpty();
$result->getById('42');
$result->extractValues('title');
$result->implode(', ', 'title');
$result->removeByValue('status', 'archived');
```

Nested Sets
-----------

[](#nested-sets)

The package includes optional nested-set base classes:

- `Frootbox\Db\Rows\NestedSet`
- `Frootbox\Db\Models\NestedSet`

They provide helpers such as `appendChild()`, `getChildren()`, `getParent()`, `getTrace()`, `getSiblings()`, and `rewriteIds()`.

Generating Explicit Accessors
-----------------------------

[](#generating-explicit-accessors)

The package ships a Composer binary:

```
vendor/bin/frootbox-db
```

Generate missing getter and setter methods for existing row classes:

```
vendor/bin/frootbox-db generate-accessors src/Persistence
```

When the command is run from a project root containing `localconfig.php`, it automatically reads the database connection from:

```
return [
    'database' => [
        'dbms' => 'mysql',
        'host' => 'localhost',
        'user' => 'root',
        'password' => 'root',
        'schema' => 'app',
    ],
];
```

Use a custom config path when needed:

```
vendor/bin/frootbox-db generate-accessors src/Persistence --localconfig=config/localconfig.php
```

Alternatively, a bootstrap file can return a `Frootbox\Db\Db` instance, or an array with a `db` key:

```
