yiisoft/db-pgsql
PostgreSQL driver for the Yii Database abstraction layer, offering PDO-based connections, schema introspection, query building, and ActiveRecord support for Yii applications and compatible frameworks.
yiisoft/db-pgsql is the PostgreSQL driver for the yiisoft/db abstraction layer — not a Laravel package. There is no service provider, facade, or Eloquent bridge; it is a DBAL you instantiate yourself and talk to through Connection → QueryBuilder / Command / Schema. That makes it a good fit for a Postgres-heavy bounded context (reporting service, ingestion worker, CLI job) living next to a Laravel app, not a replacement for Eloquent.
composer require yiisoft/db-pgsql:^2.0
Requires PHP 8.1+, ext-pdo, ext-pdo_pgsql. First steps:
composer show yiisoft/db-pgsql to confirm 2.0.1, then read vendor/yiisoft/db-pgsql/src/Connection.php for the constructor signature (driver, schema, PSR-3 logger, profiler, query cache — all optional, injected by hand).src/QueryBuilder.php and src/DDLQueryBuilder.php first — they are where every Postgres-specific capability is exposed (array literals, JSONB operators, range literals, ILIKE, SIMILAR TO, DDL with check constraints).src/Column/ and the parsers (ArrayParser, StructuredParser, RangeParser) — these define how Postgres text output becomes PHP values.use Yiisoft\Db\Pgsql\Connection;
use Yiisoft\Db\Pgsql\Driver;
use Yiisoft\Db\Pgsql\Dsn;
$db = new Connection(
new Driver(new Dsn('pgsql', '127.0.0.1', 'app', 5432, user: 'app', password: getenv('DB_PASSWORD'))),
);
First use case: a table with a text[] tags column and a jsonb payload. Create it through DDLQueryBuilder, insert with an array value, read it back through createQuery() (not createCommand()) so the Column classes typecast {a,b} into a PHP array.
Query over Command for reads. $db->createQuery()->select('*')->from('events')->all() routes each value through its Column::phpTypecast(), so text[] becomes array, jsonb becomes array, ranges become range value objects. $db->createCommand($sql)->queryAll() returns raw strings — a very common source of "why is my JSON a string?" confusion.insert()/update() are rendered as ARRAY[...] literals by the query builder. Prefer flat, list-shaped arrays; if you pass string keys, keys become an explicit dimension and Postgres will reject or mis-shape the value.Connection and compose QueryBuilder calls; map rows to DTOs yourself.DDLQueryBuilder from your own versioned scripts, or pair it with yiisoft/db-migration; do not let two tools own the same schema if Laravel's artisan migrate also touches the database.Connection::transaction(); Postgres isolation levels are exposed as constants, so set REPEATABLE READ explicitly for reporting reads instead of relying on the default.Connection from config('database.connections.pgsql'), and never call DB:: and this connection inside the same transaction — they are separate PDO handles and will deadlock under write contention.QueryBuilder/DDLQueryBuilder to add house SQL, and add custom Column classes for domain types (enums, composite types) so phpTypecast() handles them centrally.ArrayParser::parse() and StructuredParser::parse() (#477, #478), explicit use function/use const imports (#479), slimmer Composer archive (#480), and a fix for quoting array column names (#481). No API changes, no deprecations — composer update is a no-op for your code."myArray"-style identifiers could emit invalid SQL. If you had a workaround (lowercasing identifiers, aliasing, raw expressions), remove it after upgrading.all() calls.Column object rather than assuming phpTypecast() ran.{} vs NULL. An empty Postgres array round-trips as [], not null; write null checks accordingly, and be careful with strict_types array shape assumptions in DTOs.ArrayParser will happily produce nested PHP arrays from a valid Postgres literal, but writing ragged arrays back will fail server-side — validate shape before insert.Connection, dump Command::getRawSql() for the interpolated statement, and run EXPLAIN (ANALYZE, BUFFERS) through createCommand() when a QueryBuilder-generated query underperforms.Yiisoft\Db\Pgsql\*, import explicitly.config/database.php, DB::listen, and Laravel's query log do not see this connection's traffic, so instrument it separately.How can I help you explore Laravel packages today?