pear/db
PEAR DB is a database abstraction layer for PHP, offering a unified API across MySQL, PostgreSQL, SQLite, Oracle, and more. It supports prepared statements, transactions, flexible fetch modes, and error handling, making legacy PHP apps portable across database backends.
Architecture fit. pear/db is the legacy PEAR DB abstraction layer — a PHP 4/5-era DBAL built around DB::connect(), PEAR_Error returns, ? placeholders, and per-driver resource handles. Laravel's data layer is PDO-centric (Illuminate\Database\Connection → Query\Builder → Eloquent), with its own grammar, binding, transaction, and event model. pear/db implements none of Laravel's contracts, ships no service provider, facade, or config bridge, and does not sit on PDO. Fit is effectively zero for greenfield and marginal even as a legacy bridge: you end up with two connection managers, two placeholder dialects, two error models (PEAR_Error vs. QueryException), and two transaction scopes that cannot be atomically composed.
Integration feasibility. Technically possible via a thin adapter that exposes pear/db calls behind a repository interface, but the adapter is the only sane integration point — do not leak DB/PEAR_Error into Laravel application code. Real friction: sharing a single underlying connection is driver-dependent and unreliable, transaction interop across the two stacks is not supported, and Laravel's DB::transaction() will not roll back work done through pear/db. Expect to treat the boundary as a hard seam with no cross-boundary unit of work.
Technical risk. High. The codebase predates PSR standards, carries no static-analysis baseline, and is exposed to ongoing PHP 8.x deprecation pressure (dynamic properties, resource-handle semantics, removed mysql_* drivers). The 2025-11-10 release timestamp should not be read as modernization — PEAR releases are historically packaging/metadata refreshes rather than driver investment. Security posture depends entirely on disciplined prepare()/execute() usage in your callsites; the library will not catch concatenation. Supply chain is a concern: distribution is PEAR-channel-centric, so plan for Composer vendoring/forking from day one. The composite score (~4.6) overstates suitability — it is an artifact of a tiny, stable surface area, not of fitness for a modern Laravel stack; the opportunity score (2.67) is the more honest signal. Eleven stars means no community backstop, no Laravel-ecosystem answer on Stack Overflow, and a bus factor that is effectively "the PEAR maintainers."
Key questions for discovery.
pear/db actually appear today — how many callsites, which files, which drivers?Stack fit. Treat pear/db as transitional infrastructure, not a dependency. The target end state is 100% Illuminate\Database. Anything that extends the PEAR DB surface area should be treated as technical debt with an owner and a removal date.
Migration path. Strangler-fig, in this order: (1) inventory and classify usage by risk and blast radius; (2) introduce a repository/DAO interface in Laravel that hides the persistence mechanism; (3) implement that interface over pear/db for existing paths; (4) migrate module-by-module to Eloquent/Query Builder behind the same interface; (5) delete the PEAR adapter and the dependency. Do not attempt a big-bang rewrite of the data layer — the placeholder and error-handling semantics (PEAR_Error vs. exceptions) will produce silent failure modes that surface as data corruption, not as test failures.
Compatibility. Align connection parameters explicitly: charset/collation, timezone, strict SQL mode, and isolation level must match between the PEAR connection and the Laravel connection or you will get divergent behavior for identical queries. Pin PHP and driver versions in CI, and add a composer.json conflict guard if you can. Where possible, share a single credentials/config source so drift is impossible.
Sequencing. CI guard first (fail the build on new DB::connect/require 'DB.php' usage) — this is the cheapest and highest-leverage control. Then adapter layer, then one low-risk read-only module as a pilot, then write paths, then transaction-sensitive paths last. Budget for a parallel-run period with reconciliation checks on any module that migrates.
Maintenance. Minimal upstream investment and no formal advisory process you can depend on for supply-chain scanning. Vendor or fork the package, pin the version, and own the patch stream. Plan for the eventual need to patch PHP 8.x incompatibilities yourself; that work should be scoped as a known cost, not a surprise.
Support. There is no vendor and no meaningful community. Support is internal-only. Document the seam, the adapter, and the known behavioral differences (placeholder syntax, error returns, transaction limits) so on-call engineers are not reverse-engineering PEAR semantics during an incident.
Scaling. Performance is roughly native-driver performance — the wrapper is thin, so pear/db is not itself a bottleneck. The scaling risks are operational: no connection pooling strategy, no read/write splitting beyond manual configuration, and no integration with Laravel's connection lifecycle or DB::listen observability. Under load, you lose visibility precisely where you need it.
Failure modes to instrument for. Silent query failure from unchecked PEAR_Error returns; partial writes where a Laravel transaction does not cover PEAR work; driver mismatch after a PHP upgrade; charset/isolation drift between the two connections; and dependency-resolution failure when the PEAR channel or an unmaintained driver is unavailable in a fresh build.
Ramp-up. Near-zero transferability from modern Laravel experience — new engineers will not know PEAR DB and should not be asked to learn it. Budget a short internal enablement doc (call patterns, error-checking idiom, adapter usage, "do not add new usage" rule) and enforce the rule mechanically in CI. Assume onboarding cost is concentrated on the adapter and the migration plan, not on the library itself.
How can I help you explore Laravel packages today?