ziadoz/silex-capsule
Integrates Laravel's Illuminate Capsule database layer into Silex, giving you Fluent and Eloquent ORM support plus the query builder without booting a full Laravel app. Configure a connection and start querying in minutes.
ziadoz/silex-capsule is a thin Silex service provider that wires Laravel's illuminate/database Capsule manager into the Silex (Pimple) container. It is a convenience wrapper, not an ORM integration layer: you get the Capsule manager, Eloquent models, and the query builder, and nothing else (no migrations, no Artisan, no schema tooling).
Minimal setup
composer require ziadoz/silex-capsule
If Composer resolves an incompatible illuminate/database, pin it explicitly, e.g. composer require illuminate/database:^5.5 ziadoz/silex-capsule.
// src/app.php
use Ziadoz\Silex\Provider\CapsuleServiceProvider;
$app->register(new CapsuleServiceProvider(), [
'capsule.connections' => [
'default' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'app',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
],
]);
Then the manager is available as a container service — the primary key is capsule:
$app->get('/users', function () use ($app) {
return $app->json($app['capsule']->table('users')->get());
});
Where to look first
capsule.connections key name.src/Provider/CapsuleServiceProvider.php — this is the whole package. Confirm which container keys it defines (typically capsule, and often a default-connection alias), whether it calls setAsGlobal()/bootEloquent(), and whether it implements BootableProviderInterface.illuminate/database version's Capsule class, since the provider passes options straight through.First use case
Define one Eloquent model and use it from a controller — that's the fastest way to validate the wiring end to end:
// src/Model/User.php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'users';
protected $fillable = ['name', 'email'];
}
$app->get('/users/{id}', function ($id) use ($app) {
return $app->json(App\Model\User::findOrFail($id));
});
If that returns JSON, the provider, connection config, and Eloquent bootstrapping are all correct.
Keep connection config in environment-driven files. Silex's standard config/dev.php / config/prod.php pattern works well here; build the capsule.connections array from getenv() rather than hard-coding credentials. Register the provider after config is loaded and before anything that resolves $app['capsule'].
Multiple connections. The capsule.connections array is keyed by name. Add read/write or tenant entries and resolve them explicitly:
$app['capsule']->getConnection('read')->table('users')->get();
The default key is what getConnection() returns when no name is given, so keep it present even in multi-connection setups.
Prefer the container over the static facade. The provider typically calls Capsule::setAsGlobal(), which makes Capsule::table() and Eloquent's static model methods work. That's convenient in small apps, but inside services and tests pass $app['capsule'] (or a repository wrapping $app['capsule']->getConnection()) explicitly — it keeps the dependency visible and avoids two Silex app instances fighting over the same static.
Repository/service pattern. Register repositories as Pimple services that capture the connection, and inject them into Silex service controllers:
$app['repository.user'] = function ($app) {
return new App\Repository\UserRepository($app['capsule']->getConnection());
};
$app->get('/users', 'controller.user:index');
Transactions. Use the connection's helper rather than manual beginTransaction/commit, so exceptions roll back automatically:
$app['capsule']->getConnection()->transaction(function () use ($app) {
// multiple writes
});
Schema access for one-off setup. There is no Artisan integration, but you can reach the schema builder through the manager for bootstrap or test fixtures:
$schema = $app['capsule']->schema();
$schema->create('users', function ($table) {
$table->increments('id');
$table->string('email')->unique();
$table->timestamps();
});
Testing. Build a test Application that registers the provider against SQLite in-memory, then run the schema builder in setUp(). Because the connection is lazy, no database is touched until the first query, so tests that never hit the DB stay fast.
illuminate/database and PHP versions in composer.json, and don't expect PHP 8 or illuminate/* 6+ compatibility. Plan an exit path — either a small hand-rolled Capsule provider (it's ~30 lines), Doctrine DBAL, or a move to Symfony Flex.$app['db'] collisions. Many Silex projects use db for Doctrine's DBAL connection. Check the provider source for aliases and registration order; whichever provider registers last wins for a shared key. Prefer capsule to stay unambiguous.PDOException on the first query, not at boot. Test one query at startup in dev.capsule.connections entries must match illuminate/database's expected keys (driver, host, database, username, password, charset, collation, prefix). The provider does not validate or transform them.Capsule\Manager yourself (e.g. in a console script or test), you must call setAsGlobal() and bootEloquent() or model queries will fail to resolve a connection — the provider only does this for the container-managed instance.setAsGlobal() stores the manager statically; running multiple Silex applications in one process (acceptance tests, long-running workers) can leak the first app's connection into the second. Reset or rebuild the manager per app.$capsule->schema() or an external tool. Don't expect artisan-style commands.$app['capsule']->getConnection()->enableQueryLog(); then ->getQueryLog(). Wrap suspicious calls in try/catch and log the SQL plus bindings.capsule service after this provider, or fork the provider outright — it's small enough that vendoring it is often the pragmatic answer for a legacy app that needs a tweak (connection event listeners, custom connection resolver, etc.).How can I help you explore Laravel packages today?