pdo-pglite
pdo-pglite is the PostgreSQL-flavored PDO driver
for php-wasm, powered by @electric-sql/pglite.
It lets PHP use a browser-local PGlite database through the
standard PDO API.
PHP 8.1 or newer and the Vrzno extension are required. Custom
builds must set both WITH_PDO_PGLITE=1 and
WITH_VRZNO=1.
Install and Enable
Install matching runtime and database packages:
npm install php-wasm pdo-pglite @electric-sql/pglite@^0.5.8Pass the PGlite constructor into the runtime.
The pgsql: PDO driver becomes available once the
constructor is present.
import { PhpWeb } from 'php-wasm/PhpWeb.mjs';
import { PGlite } from '@electric-sql/pglite';
const php = new PhpWeb({
version: '8.4',
PGlite,
});PGlite can also be imported from a pinned CDN URL:
import { PhpWeb } from 'php-wasm/PhpWeb.mjs';
import { PGlite } from 'https://cdn.jsdelivr.net/npm/@electric-sql/[email protected]/dist/index.js';
const php = new PhpWeb({PGlite});If PGlite is not passed into the runtime, a
pgsql: connection cannot create its backing
database.
Open and Query a Database
This DSN opens an IndexedDB-backed PGlite database named
pdo-pglite-pg18:
await php.run(`<?php
$pdo = new PDO('pgsql:idb://pdo-pglite-pg18');
var_dump($pdo instanceof PDO);
`);Prepared statements support both positional and named placeholders.
await php.run(`<?php
$pdo = new PDO('pgsql:idb://pdo-pglite-pg18');
$pdo->exec('
CREATE TABLE IF NOT EXISTS notes (
id SERIAL PRIMARY KEY,
body TEXT NOT NULL
)
');
$insert = $pdo->prepare('INSERT INTO notes (body) VALUES (:body)');
$insert->execute(['body' => 'hello from php']);
foreach ($pdo->query('SELECT id, body FROM notes ORDER BY id') as $row) {
var_dump($row);
}
`);Static HTML
Import PGlite through data-imports,
then connect through PDO from PHP:
<script async type="module" src="./php-tags.mjs"></script>
<script
type="text/php"
data-stdout="#output"
data-stderr="#error"
data-imports='{
"https://cdn.jsdelivr.net/npm/@electric-sql/[email protected]/dist/index.js": ["PGlite"]
}'
><?php
$pdo = new PDO('pgsql:idb://pdo-pglite-pg18');
$pdo->exec('CREATE TABLE IF NOT EXISTS messages (body TEXT NOT NULL)');
$pdo->prepare('INSERT INTO messages (body) VALUES (?)')->execute(['hello']);
foreach ($pdo->query('SELECT body FROM messages') as $row) {
echo $row['body'], PHP_EOL;
}
?></script>
<pre id="output"></pre>
<pre id="error"></pre>Upgrade Persisted Databases
PGlite 0.5 uses PostgreSQL 18. A database directory created by PGlite 0.2 (PostgreSQL 16) cannot be opened in place by PGlite 0.5.
Export the old database logically with its original PGlite
version, restore it into a new database name such as
idb://pdo-pglite-pg18, and change the PDO DSN only
after the restore succeeds. Do not copy a
dumpDataDir() archive directly between these
PostgreSQL versions.
See the PGlite upgrade guide and PGlite tools documentation.