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

Dsn Laravel Package

micro-module/dsn

micro-module/dsn is a small PHP package for parsing, building, and handling DSN (Data Source Name) connection strings, making database or service connection details easier to manage in Laravel and PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Because micro-module/dsn has no meaningful documentation trail (0 stars, single 2020 release, no dependents), treat the repository as the spec. Before wiring it into an app:

  1. composer require micro-module/dsn
  2. Read src/ end-to-end — a DSN parser is typically one small class (Dsn, Parser, or similar) implementing parse(string $dsn): array or returning a value object. Identify the exact method names and the shape of the return value (array vs. object with scheme(), host(), port(), user(), password(), path(), query() accessors).
  3. Skim tests/ — the fixtures usually encode the supported URL shapes (scheme://user:pass@host:port/db?options), which is the fastest way to understand behavior.
  4. Check composer.json for the PHP constraint. A December 2020 release will likely require PHP 7.2–7.4 and may not declare support for 8.x; if you're on PHP 8.2+, run the tests locally before trusting it.

First use case — normalizing a DATABASE_URL env var into Laravel's config/database.php:

// config/database.php
use MicroModule\Dsn\Dsn; // confirm namespace in src/

$url = env('DATABASE_URL');

if ($url) {
    $dsn = Dsn::parse($url); // adjust to real API

    return [
        'default' => $dsn->scheme(),
        'connections' => [
            $dsn->scheme() => [
                'driver'   => $dsn->scheme() === 'postgres' ? 'pgsql' : $dsn->scheme(),
                'host'     => $dsn->host(),
                'port'     => $dsn->port(),
                'database' => ltrim($dsn->path(), '/'),
                'username' => $dsn->user(),
                'password' => $dsn->password(),
            ],
        ],
    ];
}

That single pattern — "one env var, one connection" — is the reason to reach for this package over hand-rolled parse_url() calls. Start there and only expand to other services (Redis, Mail, S3) once you've validated parsing behaves correctly for your credentials.

Implementation Patterns

Wrap it in a typed value object. Don't pass raw arrays from the parser around your app. Normalize once at the edge:

final class ConnectionConfig
{
    public function __construct(
        public readonly string $scheme,
        public readonly string $host,
        public readonly ?int $port,
        public readonly ?string $user,
        public readonly ?string $password,
        public readonly ?string $database,
        public readonly array $options,
    ) {}

    public static function fromDsn(string $dsn): self
    {
        $p = Dsn::parse($dsn); // adapt to real return shape
        return new self(
            scheme:   $p->scheme(),
            host:     $p->host(),
            port:     $p->port(),
            user:     $p->user(),
            password: $p->password(),
            database: ltrim((string) $p->path(), '/'),
            options:  $p->query(),
        );
    }
}

This isolates your codebase from the package's API, which matters given how unmaintained it is. If you ever need to swap it out for league/uri or a native parse_url() fallback, the blast radius is one class.

Map DSN schemes to Laravel drivers explicitly. DSN scheme names (postgres, mysql, rediss) rarely match Laravel drivers (pgsql, mysql, redis). Keep a lookup table rather than leaning on scheme() directly:

private const DRIVER_MAP = [
    'postgres'  => 'pgsql',
    'postgresql'=> 'pgsql',
    'mysql'     => 'mysql',
    'maria'     => 'mysql',
    'redis'     => 'redis',
    'rediss'    => 'redis',
];

Use it for side-channel services, not just the DB. Redis URLs (redis://:pw@host:6379/0), S3-compatible endpoints (s3://key:[email protected]/prefix), and mail transport URLs (smtp://user:[email protected]:2525) all benefit from the same parsing. Centralize it in a small DsnFactory service and inject that, so every service gets identical credential handling.

Multi-tenant / dynamic connections. If tenants each provide a DSN, parse on demand and register the connection at runtime:

config(['database.connections.tenant' => $tenant->dsnConfigArray()]);
DB::purge('tenant');

Cache parsed results keyed by the DSN string — parsing is cheap but you'll re-parse on every request otherwise.

Bootstrapping a testing config from DATABASE_URL. Because CI commonly injects a single URL, this package lets one env var drive both phpunit.xml DB settings and local .env without duplication.

Gotchas and Tips

  • URL-encoded credentials. Passwords containing @, :, /, or ? must be percent-encoded in the DSN. Verify the parser runs rawurldecode() on user, password, and query values — if it doesn't, you'll authenticate with literal %40 characters. Write a test asserting round-trip with a password like p@ss:w/rd.
  • Scheme casing and aliases. PostgreSQL:// vs postgres:// vs pgsql:// will not all be normalized identically. Case-fold scheme and path handling yourself rather than trusting the parser.
  • Missing port defaults. Most parsers return null for absent ports. Do not pass null to Laravel's database config — it expects an integer or env('DB_PORT', 3306). Apply driver-appropriate defaults at the mapping layer.
  • IPv6 hosts ([::1]:5432). This is the single most common bug in hand-written and small-package DSN parsers. Test it. If the package strips brackets or splits on the first :, patch around it or fall back to parse_url() for the host portion.
  • Query-string booleans and repeated keys. ?sslmode=require&charset=utf8mb4 may return strings, arrays for repeated keys, or drop them entirely. Check what query() (or equivalent) returns before relying on it for things like sslmode.
  • Trailing slash and empty path. mysql://host:3306/ should yield an empty database, not /. ltrim($path, '/') handles the common case; double-check there's no null vs '' distinction leaking into config.
  • Package staleness. Last tagged 2020-12-18, zero dependents, zero stars. Do not assume compatibility with PHP 8.2+, Laravel 10/11, or composer's strict PSR-4 autoloading changes. Vendor-lock the exact commit or fork it into app/Support/ if you only need ~60 lines.
  • Debugging: dump the raw parsed structure (dd(Dsn::parse($url))) once in a tinker session per service type. Because behavior is undocumented, this is faster than reading source twice.
  • Extension point: if the package lacks a query() accessor, you can shim it with parse_str(parse_url($dsn, PHP_URL_QUERY), $opts). In practice, wrapping the package in your own ConnectionConfig/DsnFactory is the extension point — treat the package as an implementation detail you can replace.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin