Weave Code
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

nyholm/dsn

PHP DSN parser and value object for working with connection strings. Parse and normalize DSNs for common schemes, access components like scheme, host, port, user and path, and build DSNs safely for databases, queues, mailers and more.

View on GitHub
Deep Wiki
Context7

DSN parser

Latest Version Quality Score SymfonyInsight Total Downloads

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

Install

Via Composer

composer require nyholm/dsn

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

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.

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

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

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

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

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

The following DSN syntax are not supported.

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

// Java
jdbc:informix-sqli://<server>[:<port>]/<databaseName>:informixserver=<dbservername>

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

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.

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]&host[localhost:12345]=3
  • scheme://a
  • scheme://
  • server:80
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity