b2pweb/bdf-dsn
Simple PHP DSN parser for database connection strings. Parse URL-style (mysql://user:pass@host/db?timeout=3) and PDO DSN format (mysql:host=...;dbname=...;timeout=...) into an easy-to-use object/array.
Installation
composer require b2pweb/bdf-dsn
Add the package to your composer.json under require.
First Use Case Parse a DSN string into an array for further processing:
use Bdf\Dsn\Dsn;
$parsedDsn = Dsn::parse('mysql://username:password@localhost:3306/database');
$arrayOutput = $parsedDsn->toArray();
// Output: ['scheme' => 'mysql', 'user' => 'username', 'pass' => 'password', 'host' => 'localhost', 'port' => 3306, 'path' => 'database']
Where to Look First
src/Dsn.php to understand parsing logic and available methods.tests/DsnTest.php for examples of supported DSN formats and edge cases.Parsing DSNs for Dynamic Database Connections Use the package to parse DSNs from environment variables or user input, then dynamically configure Laravel’s database connections:
$dsnString = env('CUSTOM_DB_DSN');
$parsedDsn = Dsn::parse($dsnString);
$connectionConfig = [
'driver' => str_replace('://', '', $parsedDsn->getScheme()),
'host' => $parsedDsn->getHost(),
'port' => $parsedDsn->getPort(),
'database' => ltrim($parsedDsn->getPath(), '/'),
'username' => $parsedDsn->getUser(),
'password' => $parsedDsn->getPass(),
];
config(['database.connections.custom_db' => $connectionConfig]);
Validation of User-Provided DSNs Validate DSNs submitted via forms or APIs before processing:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(['dsn' => $request->input('dsn')], [
'dsn' => function ($attribute, $value, $fail) {
try {
Dsn::parse($value);
} catch (\InvalidArgumentException $e) {
$fail('The DSN format is invalid.');
}
},
]);
Normalizing DSN Formats
Convert between different DSN formats (e.g., mysql:// to mysql:host=...) for consistency:
$urlStyleDsn = 'mysql://user:pass@localhost/db';
$parsedUrlDsn = Dsn::parse($urlStyleDsn);
$pdoStyleDsn = sprintf(
'%s:host=%s;port=%d;dbname=%s',
$parsedUrlDsn->getScheme(),
$parsedUrlDsn->getHost(),
$parsedUrlDsn->getPort(),
ltrim($parsedUrlDsn->getPath(), '/')
);
Extracting DSN Components for Custom Logic Use parsed components to build custom configurations or workflows:
$dsn = Dsn::parse('postgres://user:pass@localhost:5432/mydb');
if ($dsn->getScheme() === 'postgres') {
// Custom logic for PostgreSQL connections
$this->configurePostgresConnection($dsn);
}
Environment-Based Configuration
Parse DSNs from environment variables in your .env file and dynamically configure Laravel’s database connections:
$dsn = Dsn::parse(env('DB_DSN'));
config(['database.connections.mysql' => [
'driver' => 'mysql',
'host' => $dsn->getHost(),
'port' => $dsn->getPort(),
'database' => ltrim($dsn->getPath(), '/'),
'username' => $dsn->getUser(),
'password' => $dsn->getPass(),
]]);
Admin Panel for Database Configuration Allow administrators to input DSNs in a form, parse and validate them, then save to the database:
$request->validate([
'dsn' => 'required|dsn', // Custom validation rule
]);
$parsedDsn = Dsn::parse($request->input('dsn'));
$databaseConfig = $this->mapDsnToConfig($parsedDsn);
DatabaseConfig::create($databaseConfig);
Migration Scripts Parse DSNs from migration files or legacy configurations to update them to a standardized format:
$legacyDsn = 'mysql:host=oldhost;dbname=mydb';
$parsedLegacyDsn = Dsn::parse($legacyDsn);
$updatedDsn = sprintf(
'%s://%s:%s@%s/%s',
$parsedLegacyDsn->getScheme(),
$parsedLegacyDsn->getUser() ?? 'root',
$parsedLegacyDsn->getPass() ?? '',
$parsedLegacyDsn->getHost(),
ltrim($parsedLegacyDsn->getPath(), '/')
);
Combine with Laravel’s parseDSN
Use this package for initial parsing and validation, then fall back to Laravel’s native parseDSN for advanced features:
use Illuminate\Database\Connectors\ConnectionFactory;
$factory = new ConnectionFactory();
$config = $factory->parseDSN($dsnString); // Laravel's native parser
Custom Validation Rules Create a reusable validation rule for DSNs:
use Illuminate\Validation\Rule;
Validator::extend('dsn', function ($attribute, $value, $parameters, $validator) {
try {
Dsn::parse($value);
return true;
} catch (\InvalidArgumentException $e) {
return false;
}
});
// Usage
$request->validate(['dsn' => 'required|dsn']);
Service Provider Integration Register a service provider to handle DSN parsing across your application:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Bdf\Dsn\Dsn;
class DsnServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('dsn.parser', function () {
return new class {
public function parse(string $dsn): array
{
return Dsn::parse($dsn)->toArray();
}
};
});
}
}
Testing DSN Parsing Write tests to ensure DSNs are parsed correctly in your application:
use Bdf\Dsn\Dsn;
use PHPUnit\Framework\TestCase;
class DsnParserTest extends TestCase
{
public function testParseMysqlDsn()
{
$dsn = Dsn::parse('mysql://user:pass@localhost:3306/db');
$this->assertEquals('mysql', $dsn->getScheme());
$this->assertEquals('user', $dsn->getUser());
$this->assertEquals('pass', $dsn->getPass());
$this->assertEquals('localhost', $dsn->getHost());
$this->assertEquals(3306, $dsn->getPort());
$this->assertEquals('db', ltrim($dsn->getPath(), '/'));
}
}
Limited DSN Format Support
mysql://user:pass@host/db) and basic PDO-style DSNs (e.g., mysql:host=host).unix_socket, charset, or advanced options.parseDSN for unsupported formats.No Built-in Error Handling
InvalidArgumentException for malformed DSNs, but it lacks detailed error messages.try {
$dsn = Dsn::parse($dsnString);
} catch (\InvalidArgumentException $e) {
throw new \Exception('Invalid DSN format. Expected format: mysql://user:pass@host/db or mysql:host=host;dbname=db');
}
Case Sensitivity in Scheme Parsing
mysql, postgres)How can I help you explore Laravel packages today?