vinogradsoft / navigator
URL生成器
Requires
- php: >=8.0
- ext-intl: *
- nikic/fast-route: ^1.3
- vinogradsoft/compass: ^1.1
Requires (Dev)
- overtrue/phplint: ^2.0
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2024-09-04 18:18:16 UTC
README
创建可重用的应用程序。
开源库。
什么是 Navigator?
👉 Navigator 是一个 URL 生成器。它适用于内部应用程序导航,能够生成指向外部资源的 URL。内部导航基于命名路由定义。命名路由允许您方便地创建 URL,而无需与域名或路由定义绑定。
一般信息
该库旨在用于在其代码中使用 FastRoute 路由器应用程序。FastRoute 使用正则表达式路由定义,而 Navigator 创建与这些路由定义匹配的 URL。
为了代码一致性,路由定义被赋予名称。
route route
name determination
/‾‾‾‾‾‾‾\ /‾‾‾‾‾‾‾‾‾‾‾\
'user/view' => '/user/{id:\d+}',
这允许在不修改现有代码的情况下操作 URL。例如,为了创建名为 'user' => '/user/{id:\d+}'
的命名定义的 URL,您可以使用以下代码
/** relative url */ echo $urlBuilder->build('/user', ['id' => 100]); # /user/100 /** absolute url */ echo $urlBuilder->build('/user', ['id' => 100], true); # http://mydomain.ru/user/100
如果出于任何原因需要将地址从 /user/100
更改为 /employee/100
,只需将路由设置从 '/user/{id:\d+}'
更改为 '/employee/{id:\d+}'
即可。上面的代码将创建相对 URL /employee/100
和绝对 URL http://mydomain.ru/employee/100
。
Navigator\UrlBuilder
类对象有两个生成 URL 的方法:build
和 buildExternal
。build
方法用于应用程序内的导航,而 buildExternal
创建外部资源的 URL,并且只能生成绝对 URL。
安装
使用 composer 安装
php composer require vinogradsoft/navigator "^1.0"
需要 PHP 8.0 或更高版本。
🚀 快速入门
<?php use Navigator\ArrayRulesProvider; use Navigator\UrlBuilder; require_once dirname(__DIR__, 1) . '/vendor/autoload.php'; $urlBuilder = new UrlBuilder( 'https://vinograd.soft', new ArrayRulesProvider([ 'user' => '/user[/{var_name}]', // many other route definitions in key-value format. ]) ); echo $urlBuilder->build('/user', null, true), '<br>'; # https://vinograd.soft/user echo $urlBuilder->build('/user', ['var_name' => 'var_value'], true), '<br>'; # https://vinograd.soft/user/var_value echo $urlBuilder->build('user', ['var_name' => 'var_value'], true), '<br>'; # https://vinograd.soft/user/var_value echo $urlBuilder->build('/user', ['var_name' => 'var_value']), '<br>'; # /user/var_value echo $urlBuilder->build('user', ['var_name' => 'var_value']), '<br>'; # user/var_value
构造函数
构造函数有六个参数,其中最重要的可能是前两个。第一个参数是 $baseUrl
- 在此示例中其值为 'https://vinograd.soft'
- 这是基本 URL,用于在应用程序内生成绝对 URL。
第二个参数 $rulesProvider
接受 Navigator\RulesProvider
接口的实现实例。示例使用 Navigator\ArrayRulesProvider
实现方式,它操作一个已注册路由的常规数组。它实际上是命名路由定义的来源。
build(...)
方法的参数
$name
参数
通过 $name
参数传递路由的名称。根据此参数的值,系统了解正在处理哪个定义并将其转换为 URL。示例使用两种情况 'user'
和 '/user'
。值得注意的是,传输名称开头处的“/”字符不会以任何方式影响路由搜索;它指示系统该字符应包含在生成的 URL 的开头。系统识别此符号,然后通过名称搜索路由,排除此符号。然后,“/”由系统用作指示符,表示应将此符号包含在生成的相对 URL 的开头。
$placeholders
参数
可以是 占位符设置的数组
或 null
。
占位符设置的数组
从示例中,$urlBuilder 与路由定义 '/user[/{var_name}]'
一起工作,其中 var_name
是动态部分,换句话说是一个变量。
我们向构建方法传递了以下数组['var_name' => 'var_value']
,其中'var_name'
是路由定义中的一个变量,'var_value'是它的值,即'var_name'将被替换为何值,在我们的例子中,绝对URL的结果是https://vinograd.soft/user/var_value
。
NULL
在生成不需要在路径目录中设置静态URL的情况下使用NULL
,例如这个定义'user' => '/user'
。
示例
$urlBuilder = new UrlBuilder( 'https://vinograd.soft', new ArrayRulesProvider([ 'user' => '/user/profile', ]) ); echo $urlBuilder->build('/user', null, true); # https://vinograd.soft/user/profile
$absolute
参数
这个布尔参数告诉系统是否创建绝对或相对URL。传递true
将创建绝对地址,否则将创建相对地址。默认值是false
。
路由配置
定义名称没有严格的格式,所以您给出的名称由您决定。您可以使用格式<controller>/<action>
,例如:post/view
。或者将模块名称blog/post/view
添加到开头。
重要的是要记住一点:第一个字符不能是/
。当使用build
方法生成URL时,这个名称不正确/blog/post/view
,具有此名称的路由将无法找到,因为系统将不带/
字符开头来查找,然后抛出Navigator\RoutConfigurationException
。
正确路由名称的示例
new ArrayRulesProvider([ 'blog/post/view' => '/post/{id:\d+}', ]);
非法路由名称的示例
new ArrayRulesProvider([ // Not working warrant /blog/post/view '/blog/post/view' => '/post/{id:\d+}', ]);
在名称中不需要使用
/
符号;名称可以是blog.post.view
或没有任何分隔符的其他名称。
您可以在FastRoute库的文档中阅读如何创建路由。
占位符
方案显示了哪个占位符负责URL的哪个部分
|------------------------------:src--------------------------------------------------|
| :path ? # |
| /‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾\|
|http://grigor:password@vinograd.soft:8080/path/to/resource.json?query=value#fragment|
\__/ \___/ \_____/ \___________/ \__/ \__/
:scheme :user :password :host :port :suffix
并非所有占位符都适用于两种生成方法。下表显示了每个占位符的可用性和值的类型。
⚡ 使用占位符的示例
首先,让我们这样配置$urlBuilder
$urlBuilder = new UrlBuilder( 'https://vinograd.soft', new ArrayRulesProvider([ 'user' => '/user[/{var_name}]', 'about' => '/about[.html]', ]) );
👉 定义中的变量名称
定义中未用大括号括起来的可选参数具有
bool
类型的占位符。
示例 1。
"关于"页面在其定义中有一个后缀 - 一个没有大括号的可选参数.html
。您需要生成一个带有此后缀的URL。
echo $urlBuilder->build('about', ['.html' => true], true); # https://vinograd.soft/about.html
示例 2。
使用可选占位符指定'user' => '/user[/{var_name}]'
来生成绝对URL。
echo $urlBuilder->build('/user', ['var_name' => 'my_unique_value'], true); # https://vinograd.soft/user/my_unique_value
示例 3。
您需要生成一个带有前导/
的相对URL,定义'user' => '/user[/{var_name}]'
。
echo $urlBuilder->build('/user', ['var_name' => 'my_unique_value']); # /user/my_unique_value
示例 4。
创建一个不带前导/
的相对URL,定义'user' => '/user[/{var_name}]'
。
echo $urlBuilder->build('user', ['var_name' => 'my_unique_value']); # user/my_unique_value
示例 5。
定义'user' => '/user[/{var_name}]'
有一个可选参数var_name
。您需要生成一个不包含此参数的绝对URL。
echo $urlBuilder->build('user', null, true); # https://vinograd.soft/user
👉 :src
示例 1。
应用程序有一个包含外部资源URL的变量。您需要对URL进行一些更改
- 将其方案从
http
更改为ftp
- 添加用户名
grigor
和密码password123
- 将端口更改为
21
。
$externalAddress = 'http://another.site:8080/path/to/resource'; echo $urlBuilder->buildExternal([ ':src' => $externalAddress, ':scheme' => 'ftp', ':user' => 'grigor', ':password' => 'password123', ':port' => '21' ]); # ftp://grigor:password123@another.site:21/path/to/resource
示例 2。
将路径blog/post/41
添加到其他网站的首页URLhttp://another.site
。
echo $urlBuilder->buildExternal([ ':src' => 'http://another.site', ':path' => ['blog', 'post', 41], ]); # http://another.site/blog/post/41
👉 :scheme
示例 1。
将http://another.site
的URL方案从http
更改为https
。
echo $urlBuilder->buildExternal([ ':src' => 'http://another.site', ':scheme' => 'https', ]); # https://another.site
示例 2。
从应用程序中可用部分创建具有方案https
的URLhttps://another.site/path/to/resource
。
echo $urlBuilder->buildExternal([ ':scheme' => 'https', ':host' => 'another.site', ':path' => ['path', 'to', 'resource'], ]); # https://another.site/path/to/resource
👉 :user
示例。
为http://another.site
的URL添加用户名user
。
echo $urlBuilder->buildExternal([ ':src' => 'http://another.site', ':user' => 'user' ]); # http://user@another.site
👉 :password
此占位符仅在与
:user
占位符搭配时才有效。:user
部分必须在传递给:src
占位符的原始 URL 中存在,或者必须与:password
占位符成对传递;如果 URL 中不存在:user
,则会抛出Navigator\BadParameterException
。
示例。
为 URL ftp://another.site:21
添加用户名 grigor
和密码 password123
。
echo $urlBuilder->buildExternal([ ':src' => 'ftp://another.site:21', ':user' => 'grigor', ':password' => 'password123' ]); # ftp://grigor:password123@another.site:21
👉 :host
:host
占位符与:scheme
占位符一起使用。在不使用:src
占位符,而想从部分创建 URL 的情况下,则需要:host
和':scheme'
;如果它们任何一个缺失,则会抛出Navigator\BadParameterException
。:host
是唯一一个不会用传递的:src
占位符覆盖其 URL 部分的占位符。
示例。
需要创建 URL http://another.site
。
echo $urlBuilder->buildExternal([ ':scheme' => 'http', ':host' => 'another.site' ]); # http://another.site
👉 :port
示例。
创建一个端口为 5000
的 URL http://another.site
。
echo $urlBuilder->buildExternal([ ':scheme' => 'http', ':host' => 'another.site', ':port' => '5000' ]); # http://another.site:5000
👉 :path
示例 1。
需要使用类型为 array
的占位符值创建 URL https://another.site/path/to
。
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site', ':path' => ['path', 'to'] ]); # https://another.site/path/to
示例 2。
使用类型为 string
的占位符值生成 URL https://another.site/path/to
。
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site', ':path' => 'path/to' ]); # https://another.site/path/to
👉 :suffix
关于后缀有一个注意事项,如果您使用
:src
占位符传递带有后缀的 URL,您无法使用:suffix
占位符覆盖它,您只能添加它,因为后缀可以是任何字符串,它不会被解析,并将成为路径的一部分。
示例 1。
向 URL https://another.site/path/to
添加 .html
扩展名。
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site', ':path' => 'path/to', ':suffix' => '.html' ]); # https://another.site/path/to.html
示例 2。
向 URL https://another.site/path/to?q=value#news
添加后缀 -city
。
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site/path/to?q=value#news', ':suffix' => '-city' ]); # https://another.site/path/to-city?q=value#news
👉 占位符 ?
示例 1。
将值 Hello world
的 s
参数添加到 https://another.site
URL。
echo $urlBuilder->buildExternal([':src' => 'https://another.site', '?' => ['s' => 'Hello world']]); # https://another.site/?s=Hello%20world
示例 2。
系统已准备好参数 s=Hello world
,您需要将其添加到 URL https://another.site
。
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site', '?' => 's=Hello world' ]); # https://another.site/?s=Hello%20world
示例 3。
需要创建一个 URL,用于链接到另一个网站的搜索结果 https://another.site
,并带有以下参数
[ 'search' => [ 'blog' => [ 'category' => 'news', 'author' => 'Grigor' ] ] ]
代码
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site', '?' => [ 'search' => [ 'blog' => [ 'category' => 'news', 'author' => 'Grigor' ] ] ] ]); # https://another.site/?search%5Bblog%5D%5Bcategory%5D=news&search%5Bblog%5D%5Bauthor%5D=Grigor
👉 占位符 #
示例 1。
任务是生成指向 vinogradsoft/compass
库文档快速入门段落的链接地址。
echo $urlBuilder->buildExternal([ ':src' => 'https://github.com/vinogradsoft/compass', '#' => 'quick-start' ]); # https://github.com/vinogradsoft/compass#quick-start
👉 :strategy
要使用 URL 生成策略,您必须实现
Compass\UrlStrategy
接口或从Compass\DefaultUrlStrategy
类继承。有关策略操作原理的更多详细信息,请参阅 Compass 库的文档。
示例 1。
任务是创建一个生成具有 refid
参数等于 222
的引用链接 URL 的策略。
策略代码
<?php namespace <your namespace>; use Compass\DefaultUrlStrategy; use Compass\Url; class ReferralUrlStrategy extends DefaultUrlStrategy { /** * @inheritDoc */ public function updateQuery(array $items): string { $items['refid'] = 222; return http_build_query($items, '', '&', PHP_QUERY_RFC3986); } /** * @inheritDoc */ public function forceUnlockMethod( bool &$schemeState, int &$authoritySate, int &$relativeUrlState, array $items, array $pathItems, array $queryItems, bool $updateAbsoluteUrl, ?string $suffix = null ): void { $relativeUrlState &= ~Url::QUERY_STATE; } }
让我们向 $urlBuilder
构造函数添加一个策略
$urlBuilder = new UrlBuilder( 'https://vinograd.soft', new ArrayRulesProvider([ 'user' => '/user[/{var_name}]' ]), ['referral' => new ReferralUrlStrategy()] );
生成 URL
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site/path/to/resource', ':strategy' => 'referral' ]); # https://another.site/path/to/resource?refid=222
示例 2。
让我们从本段落的示例 1 中获取策略,并将其作为生成外部 URL 的默认策略。
让我们替换 Compass\Url
类实例中的策略,并将其传递给我们的 $urlBuilder
构造函数的第五个参数($externalUrl
)。
$externalUrl = Url::createBlank(); $externalUrl->setUpdateStrategy(new ReferralUrlStrategy()); $urlBuilder = new UrlBuilder( 'https://vinograd.soft', new ArrayRulesProvider([ 'user' => '/user[/{var_name}]' ]), [], null, $externalUrl );
生成 URL
echo $urlBuilder->buildExternal([ ':src' => 'https://another.site/path/to/resource' ]); # https://another.site/path/to/resource?refid=222
👉 :idn
示例 1。
任务是将 URL https://россия.рф
转换为 panycode。
echo $urlBuilder->buildExternal([':src' => 'https://россия.рф', ':idn' => true]); # https://xn--h1alffa9f.xn--p1ai
测试
php composer 测试
贡献
有关详细信息,请参阅 CONTRIBUTING。
许可
MIT 许可证(MIT)。有关更多信息,请参阅许可 文件。