Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dibi Laravel Package

cuonggt/dibi

Laravel integration for Dibi, the lightweight PHP database abstraction layer. Provides configuration, service provider, and facades to use Dibi’s fluent query builder and database access inside Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require cuonggt/laravel-dibi
php artisan dibi:publish   # first install only

dibi:publish publishes the package config, migrations-free dashboard assets and the compiled front-end under public/vendor/.... Since v1.x it is not required on every upgrade — v1.0.4 explicitly ships no asset changes. Re-run it only when the release notes say assets changed, and prefer running it in CI/deploy so you notice when a published-asset check fails.

Where to look first

  1. config/dibi.php — the connection block and dashboard options. Note that the package's dashboard now selects from the connections your application already configures under config/database.php, so DB_HOST/DB_DATABASE are not a separate world to maintain the way they were in 0.x. Add the legacy/reporting connection to database.connections and it becomes selectable.
  2. php artisan route:list — find the dashboard route the package registers. The dashboard is now the fastest way to confirm the package is wired up at all: it renders your configured connections, tables, columns and indexes.
  3. bootstrap/providers.php — on Laravel 11+ verify the provider is listed exactly once.
  4. The bound dibi\Connection — resolve it from the container and you have the full Dibi API (query(), fetch(), fetchAll(), getFluent()).

First use case

Two day-one scenarios, in order:

Look at the dashboard. Before writing a line of code, open the dashboard route and switch between connections. If a connection is missing there, it is missing from config/database.php — fix that before debugging the container binding.

Then query a second database. A legacy schema, a read replica or a reporting warehouse, queried with Dibi's fluent builder while the rest of the app stays on Eloquent:

use Dibi\Connection;

$rows = app(Connection::class)
    ->select('*')
    ->from('legacy_orders')
    ->where('created_at >= %d', $since)
    ->fetchAll();

If you are coming from the previously assessed v0.7.0, the jump to v1.x is a major version, not a patch. Read the intervening release notes; the dashboard, the connection selector and the per-driver metadata repositories did not exist then, and the "the package ignores config/database.php" assumption from 0.x is no longer accurate.

Implementation Patterns

Resolve the connection, don't instantiate it. Always pull Dibi\Connection from the container so config changes and test bindings apply:

final class LegacyOrderRepository
{
    public function __construct(private readonly Connection $dibi) {}

    public function recent(int $limit): array
    {
        return $this->dibi->select('id, total, created_at')
            ->from('legacy_orders')
            ->orderBy('created_at')->desc()
            ->limit($limit)
            ->fetchAll();
    }
}

Fluent builder for reads, raw SQL for the awkward stuff. For CTEs, window functions or vendor hints, drop to query() with Dibi modifiers — safer than interpolation:

$this->dibi->query('SELECT * FROM t WHERE status = %s AND owner_id = %i', $status, $userId);

%s string, %i integer, %n identifier, %sql raw fragment. These are Dibi's own modifiers, not PDO ? placeholders — mixing the two is the most common runtime error with this package.

Transactions. Use Dibi's own transaction API rather than wrapping writes in Laravel's DB::transaction(). The two managers are independent, so nesting gives no atomicity guarantee across both:

$this->dibi->begin();
try {
    // ... writes
    $this->dibi->commit();
} catch (\Throwable $e) {
    $this->dibi->rollback();
    throw $e;
}

Split responsibilities with Eloquent. Eloquent owns writes, validation, events and relationships; Dibi owns bulk exports, cross-schema reports and anything where you would otherwise fight the ORM. Keep each table owned by exactly one of the two so timestamp/soft-delete behaviour doesn't diverge.

Map results at the boundary. Dibi returns plain arrays or row objects. Convert to DTOs or collections in the repository so the rest of the app never sees a Dibi type:

return collect($rows)->map(fn (array $r) => new OrderSummary(...));

Multiple connections. Define the extra connection under config/database.php, then select it in the dashboard. The dashboard remembers your selection across requests — which is convenient, and is exactly the mechanism that produced the 1.0.4 500-loop fix, so treat the remembered value as state that can go stale.

Testing. Because the connection is a container binding, swap it freely: bind a configured connection in your test case, or point the config at SQLite in-memory. Dibi keeps static state, so reset it between tests (the package's own suite does) — otherwise connection or driver state leaks across tests in a way that looks like flakiness.

Gotchas and Tips

v1.0.4 upgrade — a patch release, no breaking changes and no asset changes:

composer update cuonggt/laravel-dibi
php artisan config:clear
php artisan view:clear

dibi:publish is not required. Do not cargo-cult the republish step from 0.x-era checklists; running it on a release with unchanged assets creates noise in your diff, and if you commit published assets you have to audit that diff for nothing.

The remembered-connection 500 loop. Before 1.0.4, selecting a connection your app does not configure under database.connections was remembered indefinitely, and every later dashboard request 500'd — with the selector on the page that no longer rendered, so there was no way back through the UI. 1.0.4 discards an unusable remembered selection, falls back to the first available connection, and rejects such a selection up front. If you are on <1.0.4 and hitting this, clearing the cached/session selection is the manual escape hatch; upgrading is the real fix. If you removed a connection from config/database.php and left one behind, this is why.

Dashboard JSON contract change. TableIndex now serialises only its mapped fields instead of sending each index row twice, cutting roughly 40% of the index payload per dashboard load. If you scrape the dashboard's JSON, snapshot it in tests, or cache it, expect the raw/duplicated index representation to be gone. The mapped fields are unchanged, and this contract is now covered by tests — but your own assertions are not.

Published-asset check. The package verifies published assets and raises errors when they are missing or stale; v1.0.4 brought that path (including the console short-circuit that had excluded it from the suite) under test. Run it in deploy/CI rather than discovering staleness from a broken dashboard in production.

Driver parity is real but not identical. Metadata is served by per-driver repositories behind DatabaseRepositoryFactory, now tested for MySQL, PostgreSQL and SQLite, with an explicit error for unsupported drivers. Column and index metadata will still differ subtly by driver — SQLite is fine for tests and demos, but do not assume a dashboard that renders perfectly on SQLite proves everything about your production MySQL/Postgres schema.

Config caching. env() in config/dibi.php is fine; after php artisan config:cache any env() call outside config files returns null. Keep all environment lookups in the config file and read via config(...) elsewhere.

Dibi and Laravel log separate worlds. Dibi queries do not appear in Laravel's query log, Telescope, or DB::listen(). Enable Dibi's own logger/profiler in the config or you will be debugging blind — the number-one surprise for developers coming from DB::table().

Connection parity. Set charset, collation and timezone explicitly on the Dibi connection to match your Laravel connections. Mismatched timezones between an Eloquent write and a Dibi read is a classic off-by-hours bug that looks like data corruption.

Driver choice. Dibi talks to the database through its own drivers, not Laravel's PDO instances. SSL options must be duplicated, and connection limits are consumed twice — count Dibi as a separate pool if your app has a tight cap.

Extension points. Use Dibi's event handlers ($connection->onEvent[] = ...) for logging and profiling, and bind your own subclass of Dibi\Connection in a service provider for per-query behaviour. Change driver options in the published config; never edit files under vendor/, which any asset or metadata change will overwrite.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator