nyholm/dsn

以强大和灵活的方式解析DSN字符串

维护者

详细信息

github.com/Nyholm/dsn

主页

源代码

问题

资助包维护!
Nyholm

安装量: 14,739,133

依赖项: 33

建议者: 0

安全: 0

星标: 104

关注者: 5

分叉: 11

开放性问题: 3

2.0.1 2021-11-18 09:23 UTC

This package is auto-updated.

Last update: 2024-09-18 15:20:46 UTC


README

Latest Version Quality Score SymfonyInsight Total Downloads

将DSN字符串解析为值对象,以便更容易使用、传递和处理。

安装

通过Composer

composer require nyholm/dsn

快速使用

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

DSN字符串格式

DSN是一种用于配置许多服务的字符串。常见的DSN可能看起来像一个URL,其他则像文件路径。

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

这两种类型都可以有参数、用户和密码。我们使用的确切定义可以在页面底部找到。

DSN函数

DSN可能包含零个或多个函数。DSN解析器支持函数语法,但不支持其功能本身。函数参数必须用空格或逗号分隔。以下是一些示例函数。

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)

解析

有两种解析方法;DsnParser::parse()DsnParser::parseFunc()。后者用于支持DSN函数的情况。

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

如果支持函数(如Symfony Mailer组件),我们可以使用 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"

当使用 DsnParser::parseFunc() 对不包含任何DSN函数的字符串进行解析时,解析器会自动添加一个默认的 "dsn" 函数。这是为了提供方法的一致返回类型。

使用 DsnParser::parseFunc() 时,字符串 redis://127.0.0.1 将自动转换为 dsn(redis://127.0.0.1)

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"

解析无效的DSN

如果您尝试解析无效的DSN字符串,将抛出 InvalidDsnException

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

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

消费

解析DSN字符串的结果是 DsnFunctionDsn。一个 DsnFunction 有一个 nameargument,可能还有 parameters。一个参数是一个 DsnFunction 或一个 Dsn

Dsn 可以是一个 PathUrl。所有3个对象都有用于获取DSN字符串部分的方法。

  • getScheme()
  • getUser()
  • getPassword()
  • getHost()
  • getPort()
  • getPath()
  • getParameters()

您还可以使用 with* 方法替换DSN的部分。DSN是不可变的,您将得到一个新的对象。

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"

不受支持

智能合并选项

当前的DSN是有效的,但是消费者需要确保host1和host2都包含 global_option

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

特殊DSN

以下DSN语法不受支持。

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

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

我们不支持像ODBC连接这样的DSN字符串

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

然而,我们支持“仅参数”

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

定义

没有官方的DSN RFC。我们已将DSN配置字符串定义为使用以下定义。DSN的“URL看起来”部分基于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]+

支持格式的示例

  • 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