PHPackages                             nyholm/dsn - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. nyholm/dsn

ActiveLibrary[Database &amp; ORM](/categories/database)

nyholm/dsn
==========

Parse your DSN strings in a powerful and flexible way

2.0.1(4y ago)10622.9M—8.4%11[1 issues](https://github.com/Nyholm/dsn/issues)[2 PRs](https://github.com/Nyholm/dsn/pulls)20MITPHPPHP &gt;=7.1CI passing

Since Mar 3Pushed 3y ago3 watchersCompare

[ Source](https://github.com/Nyholm/dsn)[ Packagist](https://packagist.org/packages/nyholm/dsn)[ Docs](http://tnyholm.se)[ GitHub Sponsors](https://github.com/Nyholm)[ RSS](/packages/nyholm-dsn/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (1)Versions (10)Used By (20)

DSN parser
==========

[](#dsn-parser)

[![Latest Version](https://camo.githubusercontent.com/525e755e6d66cbae771e68bf95d74e0e54fd3bf15298d04fd27fa2e4dc397307/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f4e79686f6c6d2f64736e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/Nyholm/dsn/releases)[![Quality Score](https://camo.githubusercontent.com/5aa530b0117598f8e74c053c169b3d0c89adef7d741aa00b8afbfba8bc61927a/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f4e79686f6c6d2f64736e2e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/Nyholm/dsn)[![SymfonyInsight](https://camo.githubusercontent.com/979242fdf66b3e452a16dd23cebef215916ffdfef15f652b3e75fd21ed960d24/68747470733a2f2f696e73696768742e73796d666f6e792e636f6d2f70726f6a656374732f66653161373062372d366261392d343234642d393231372d3533383333653437623037662f6d696e692e737667)](https://insight.symfony.com/projects/fe1a70b7-6ba9-424d-9217-53833e47b07f)[![Total Downloads](https://camo.githubusercontent.com/3ea7a3db5ce62e9fa4d9f8c5b136f276deae87d07e5e595f1b7facaf9f765ed6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e79686f6c6d2f64736e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nyholm/dsn)

Parse DSN strings into value objects to make them easier to use, pass around and manipulate.

Install
-------

[](#install)

Via Composer

```
composer require nyholm/dsn
```

Quick usage
-----------

[](#quick-usage)

```
use Nyholm\Dsn\DsnParser;

$dsn = DsnParser::parse('http://127.0.0.1/foo/bar?key=value');
echo get_class($dsn); // "Nyholm\Dsn\Configuration\Url"
echo $dsn->getHost(); // "127.0.0.1"
echo $dsn->getPath(); // "/foo/bar"
echo $dsn->getPort(); // null
```

The DSN string format
---------------------

[](#the-dsn-string-format)

A DSN is a string used to configure many services. A common DSN may look like a URL, other look like a file path.

```
memcached://127.0.0.1
mysql://user:password@127.0.0.1:3306/my_table
memcached:///var/local/run/memcached.socket?weight=25

```

Both types can have parameters, user, password. The exact definition we are using is found [at the bottom of the page](#definition).

### DSN Functions

[](#dsn-functions)

A DSN may contain zero or more functions. The DSN parser supports a function syntax but not functionality itself. The function arguments must be separated with space or comma. Here are some example functions.

```
failover(dummy://a dummy://a)
failover(dummy://a,dummy://a)
failover:(dummy://a,dummy://a)
roundrobin(dummy://a failover(dummy://b dummy://a) dummy://b)

```

Parsing
-------

[](#parsing)

There are two methods for parsing; `DsnParser::parse()` and `DsnParser::parseFunc()`. The latter is for situations where DSN functions are supported.

```
use Nyholm\Dsn\DsnParser;

$dsn = DsnParser::parse('scheme://127.0.0.1/foo/bar?key=value');
echo get_class($dsn); // "Nyholm\Dsn\Configuration\Url"
echo $dsn->getHost(); // "127.0.0.1"
echo $dsn->getPath(); // "/foo/bar"
echo $dsn->getPort(); // null
```

If functions are supported (like in the Symfony Mailer component) we can use `DsnParser::parseFunc()`:

```
use Nyholm\Dsn\DsnParser;

$func = DsnParser::parseFunc('failover(sendgrid://KEY@default smtp://127.0.0.1)');
echo $func->getName(); // "failover"
echo get_class($func->first()); // "Nyholm\Dsn\Configuration\Url"
echo $func->first()->getHost(); // "default"
echo $func->first()->getUser(); // "KEY"
```

```
use Nyholm\Dsn\DsnParser;

$func = DsnParser::parseFunc('foo(udp://localhost failover:(tcp://localhost:61616,tcp://remotehost:61616)?initialReconnectDelay=100)?start=now');
echo $func->getName(); // "foo"
echo $func->getParameters()['start']; // "now"

$args = $func->getArguments();
echo get_class($args[0]); // "Nyholm\Dsn\Configuration\Url"
echo $args[0]->getScheme(); // "udp"
echo $args[0]->getHost(); // "localhost"

echo get_class($args[1]); // "Nyholm\Dsn\Configuration\DsnFunction"
```

When using `DsnParser::parseFunc()` on a string that does not contain any DSN functions, the parser will automatically add a default "dsn" function. This is added to provide a consistent return type of the method.

The string `redis://127.0.0.1` will automatically be converted to `dsn(redis://127.0.0.1)`when using `DsnParser::parseFunc()`.

```
use Nyholm\Dsn\DsnParser;

$func = DsnParser::parseFunc('smtp://127.0.0.1');
echo $func->getName(); // "dsn"
echo get_class($func->first()); // "Nyholm\Dsn\Configuration\Url"
echo $func->first()->getHost(); // "127.0.0.1"

$func = DsnParser::parseFunc('dsn(smtp://127.0.0.1)');
echo $func->getName(); // "dsn"
echo get_class($func->first()); // "Nyholm\Dsn\Configuration\Url"
echo $func->first()->getHost(); // "127.0.0.1"
```

### Parsing invalid DSN

[](#parsing-invalid-dsn)

If you try to parse an invalid DSN string a `InvalidDsnException` will be thrown.

```
use Nyholm\Dsn\DsnParser;
use Nyholm\Dsn\Exception\InvalidDsnException;

try {
  DsnParser::parse('foobar');
} catch (InvalidDsnException $e) {
  echo $e->getMessage();
}
```

Consuming
---------

[](#consuming)

The result of parsing a DSN string is a `DsnFunction` or `Dsn`. A `DsnFunction` has a `name`, `argument` and may have `parameters`. An argument is either a `DsnFunction`or a `Dsn`.

A `Dsn` could be a `Path` or `Url`. All 3 objects has methods for getting parts of the DSN string.

- `getScheme()`
- `getUser()`
- `getPassword()`
- `getHost()`
- `getPort()`
- `getPath()`
- `getParameters()`

You may also replace parts of the DSN with the `with*` methods. A DSN is immutable and you will get a new object back.

```
use Nyholm\Dsn\DsnParser;

$dsn = DsnParser::parse('scheme://127.0.0.1/foo/bar?key=value');

echo $dsn->getHost(); // "127.0.0.1"
$new = $dsn->withHost('nyholm.tech');

echo $dsn->getHost(); // "127.0.0.1"
echo $new->getHost(); // "nyholm.tech"
```

Not supported
-------------

[](#not-supported)

### Smart merging of options

[](#smart-merging-of-options)

The current DSN is valid, but it is up to the consumer to make sure both host1 and host2 has `global_option`.

```
redis://(host1:1234,host2:1234?node2_option=a)?global_option=b

```

### Special DSN

[](#special-dsn)

The following DSN syntax are not supported.

```
// Rust
pgsql://user:pass@tcp(localhost:5555)/dbname

// Java
jdbc:informix-sqli://[:]/:informixserver=

```

We do not support DSN strings for ODBC connections like:

```
Driver={ODBC Driver 13 for SQL Server};server=localhost;database=WideWorldImporters;trusted_connection=Yes;

```

However, we do support "only parameters":

```
ocdb://?Driver=ODBC+Driver+13+for+SQL+Server&server=localhost&database=WideWorldImporters&trusted_connection=Yes

```

Definition
----------

[](#definition)

There is no official DSN RFC. We have defined a DSN configuration string as using the following definition. The "URL looking" parts of a DSN is based from [RFC 3986](https://tools.ietf.org/html/rfc3986).

```
configuration:
  { function | dsn }

function:
  function_name[:](configuration[,configuration])[?query]

function_name:
  REGEX: [a-zA-Z0-9\+-]+

dsn:
  { scheme:[//]authority[path][?query] | scheme:[//][userinfo]path[?query] | host:port[path][?query] }

scheme:
  REGEX: [a-zA-Z0-9\+-\.]+

authority:
  [userinfo@]host[:port]

userinfo:
  { user[:password] | :password }

path:
  "Normal" URL path according to RFC3986 section 3.3.
  REGEX: (/? | (/[a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=:@]+)+)

query:
  "Normal" URL query according to RFC3986 section 3.4.
  REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=:@]+

user:
  This value can be URL encoded.
  REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+

password:
  This value can be URL encoded.
  REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+

host:
  REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+

post:
  REGEX: [0-9]+

```

Example of formats that are supported:

- scheme://127.0.0.1/foo/bar?key=value
- scheme://user:pass@127.0.0.1/foo/bar?key=value
- scheme:///var/local/run/memcached.socket?weight=25
- scheme://user:pass@/var/local/run/memcached.socket?weight=25
- scheme:?host\[localhost\]&amp;host\[localhost:12345\]=3
- scheme://a
- scheme://
- server:80

###  Health Score

47

—

FairBetter than 94% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity63

Solid adoption and visibility

Community29

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 91.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~169 days

Recently: every ~146 days

Total

9

Last Release

1643d ago

Major Versions

0.1.1 → 1.0.02018-12-11

1.0.1 → 2.0.0-beta12020-10-03

PHP version history (3 changes)0.1.0PHP ^5.5 || ^7.0

2.0.0-beta1PHP &gt;=7.2.5

2.0.0-beta2PHP &gt;=7.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/401ccc5eea13c60cf807ae982af00e368e2166e2f26d8eb541dcd881a57385bc?d=identicon)[Nyholm](/maintainers/Nyholm)

---

Top Contributors

[![Nyholm](https://avatars.githubusercontent.com/u/1275206?v=4)](https://github.com/Nyholm "Nyholm (32 commits)")[![chapa](https://avatars.githubusercontent.com/u/457659?v=4)](https://github.com/chapa "chapa (1 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (1 commits)")[![Toflar](https://avatars.githubusercontent.com/u/481937?v=4)](https://github.com/Toflar "Toflar (1 commits)")

---

Tags

dsnparserdatabasedsndsn parser

### Embed Badge

![Health badge](/badges/nyholm-dsn/health.svg)

```
[![Health](https://phpackages.com/badges/nyholm-dsn/health.svg)](https://phpackages.com/packages/nyholm-dsn)
```

###  Alternatives

[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[moloquent/moloquent

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)

120114.6k7](/packages/moloquent-moloquent)[craftcms/fix-fks

Restore missing foreign key constraints in the database.

1217.4k](/packages/craftcms-fix-fks)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
