vinogradsoft / compass
用于处理地址的库。支持磁盘文件路径和URL。
Requires
- php: >=8.0
- ext-intl: *
Requires (Dev)
- overtrue/phplint: ^3.1
- phpunit/phpunit: ^9.6.13
This package is auto-updated.
Last update: 2024-09-04 18:21:45 UTC
README
创建可重用的应用程序。
开源库。
Compass 是什么?
👉 Compass 是一个用于处理 URL 和硬盘文件路径的库。它包括简化数据操作的工具。该库的目标是便于处理 URL 和文件位置上的数据。
一般信息
Compass 可以用于各种 PHP 应用程序中处理文件路径和 URL。它包括两个主要组件:Compass\Path
和 Compass\Url
。这两个组件都是独立的对象,提供了一组简单数据操作的方法。Compass\Path
提供用于处理目录的工具,包括在路径字符串中查找、替换和检查目录,以及更改它们的顺序。反过来,Compass\Url
提供用于处理 URL 的功能,允许您创建、检索和修改 URL 的各个部分。
这两个组件都遵循相似的原则,首先收集必要的参数,然后使用特殊的 updateSource()
方法将这些参数应用于结果。
安装
使用 composer 安装
php composer require vinogradsoft/compass "^1.0"
需要 PHP 8.0 或更高版本。
URL 组件
🚀 快速入门
<?php require_once dirname(__DIR__, 1) . '/vendor/autoload.php'; use \Compass\Url; $url = Url::createBlank(); $url->setScheme('http')->setUser('grigor')->setPassword('password')->setHost('vinograd.soft') ->setPort('8080')->setPath('/path/to/resource')->setSuffix('.json') ->setArrayQuery(['query' => 'value',])->setFragment('fragment'); $url->updateSource(); echo '<br><br><b>Authority:</b> ', $url->getAuthority(); echo '<br><b>Base Url:</b> ', $url->getBaseUrl(); echo '<br><b>Relative Url:</b> ', $url->getRelativeUrl(); echo '<br><b>Absolute Url:</b> ', $url->getSource(), '<br>'; echo '<br><b>Scheme:</b> ', $url->getScheme(); echo '<br><b>User:</b> ', $url->getUser(); echo '<br><b>Password:</b> ', $url->getPassword(); echo '<br><b>Host:</b> ', $url->getHost(); echo '<br><b>Port:</b> ', $url->getPort(); echo '<br><b>Path:</b> ', $url->getPath(); echo '<br><b>Suffix:</b> ', $url->getSuffix(); echo '<br><b>Query:</b> ', $url->getQuery(); echo '<br><b>Fragment:</b> ', $url->getFragment(); $url->setSource('http://россия.рф'); $url->setConversionIdnToAscii(true)->updateSource(); echo '<br><br><b>new URL:</b> ',$url; #http://xn--h1alffa9f.xn--p1ai
创建 Compass\Url 类的实例
Compass\Url
类可以通过调用静态方法 createBlank()
或使用 new
操作符来实例化。createBlank()
方法以其使用自己的原型进行克隆而著称。该方法有两个可选参数:$isIdnToAscii
和 $updateStrategy
,用于确定是否应将主机转换为 punycode 以及使用哪种 URL 更新策略。
第一个参数,$isIdnToAscii
,确定是否应转换主机。如果设置为 true
,则转换主机;如果为 false
,则不转换主机。
第二个参数,$updateStrategy
,确定 URL 更新策略。该策略涉及创建 URL 各个组件的方法。
要使用 new
操作符创建 Compass\Url
类的新实例,必须传递一个必需参数 - 作为字符串的原生 URL。
生成 URL 的方法
可以使用以下方法设置参数:
- 构造函数
setSource
方法setAll
方法- 特定于 URL 某个部分的特定方法(如快速入门中所示)。
⚡ 示例
👉 通过构造函数
$url = new Url('http://grigor:password@vinograd.soft:8080/path/to/resource?query=value#fragment');
👉 使用 setSource
方法
$url->setSource('http://grigor:password@vinograd.soft:8080/path/to/resource?query=value#fragment');
👉 使用 setAll
方法
$url->setAll([ ':host' => 'host.ru', ':scheme' => 'http', ':user' => 'user', ':password' => 'password', ':port' => '80', ':path' => ['path', 'to', 'resource'], '?' => ['key' => 'value', 'key2' => 'value2'], '#' => 'fragment', ':suffix' => '.json', ]);
👉 使用负责特定 URL 部分的特定方法。
$url->setScheme('http')->setUser('grigor')->setPassword('password')->setHost('vinograd.soft') ->setPort('8080')->setPath('/path/to/resource')->setSuffix('.json') ->setArrayQuery(['query' => 'value',])->setFragment('fragment');
在前两种情况下,后缀不被识别。在这种情况下,必须使用单独的 $url->setSuffix(.json);
方法设置后缀,这是唯一可以管理它的方法。
❗ 后缀不会被解析,因为它可以是任何字符串,并且不必以点开头。如果传递带有后缀的 URL,则后缀成为
path
的一部分。
应用更改
为了使更改的参数生效,您必须调用 $url->updateSource()
方法。此方法有两个可选参数 - $updateAbsoluteUrl
和 $suffix
。$updateAbsoluteUrl
参数的值决定了是否更新整个 URL 或仅更新其相对部分。默认值为 true
,也就是说,默认情况下将尝试更新整个 URL。$suffix
参数的类型为 string
,允许您在更新时设置后缀。
参数应用后,您可以使用 $url->getSource()
方法获取更新后的结果。
升级策略
📢 更新策略是一个对象,它结合所有输入来创建一个最终的 URL。此对象必须是
Compass\UrlStrategy
接口的实现。在系统中,执行此功能的类称为Compass\DefaultUrlStrategy
。
策略是为了控制 URL 创建过程而发明的。它包含一系列方法,每个方法对应于 URL 的一个部分,其中参数被连接。哪些方法将参与更新,由 Compass\Url
对象根据各部分的状态确定。有一些标志表示哪些区域需要重新创建。为了便于理解,我们可以将此与分成若干部分“A”、“B”、“C”、“D”的公路和负责该公路的道路公司进行类比。理想情况下,公路应该始终保持平坦。当公路的一部分,例如"C",损坏时,维修团队就会去该部分进行维修。您也可以想象一个 URL,其中公路是一串具有逻辑部分(部分)的字符串。维修团队是更新策略中的方法。道路公司是 Compass\Url
对象。
策略有六个方法用于创建 URL 的部分
updateAuthority()
updateBaseUrl()
updateQuery()
updatePath()
updateRelativeUrl()
updateAbsoluteUrl()
.
通过为 URL 设置任何参数,系统会更改该部分的状态,就像损坏了传递参数的该部分一样。在调用 $url->updateSource();
方法后,适当的策略方法将包含在操作中。
❗ 重要的一点是要记住,
Compass\Url
对象存储了用户安装的初始部分和每个策略方法的输出结果。
方法的实现可以分为三个级别。
LEVEL 3
|--------------------------------updateAbsoluteUrl()---------------------------------|
| |
| LEVEL 2 |
|---------------updateBaseUrl()-----------|------------updateRelativeUrl()-----------|
| | |
| LEVEL 1 |
| updateAuthority() | updatePath() updateQuery() |
| /‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\|/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾‾‾\ |
|http://grigor:password@vinograd.soft:8080/path/to/resource.json?query=value#fragment|
第三级方法 updateAbsoluteUrl()
总是执行;它组合了第二级方法的保存结果。第二级方法 updateBaseUrl()
和 updateRelativeUrl()
组合了第一级的结果。在第一级,updateAuthority()
、updatePath()
和 updateQuery()
在各自的范围内将原始部分粘合在一起。
状态操作
状态存储在 Compass\Url
类的几个字段中:$authoritySate
、$relativeUrlState
和 $schemeState
。 $authoritySate
和 $relativeUrlState
的类型为 int
,$schemeState
的类型为 bool
。$authoritySate
和 $relativeUrlState
的状态由位操作控制。下面是一个代码示例,显示了状态完好时的默认值
const USER_STATE = 1 << 0; const PASSWORD_STATE = 1 << 1; const HOST_STATE = 1 << 2; const PORT_STATE = 1 << 3; const PATH_STATE = 1 << 0; const QUERY_STATE = 1 << 1; const FRAGMENT_STATE = 1 << 2; const AUTHORITY_WHOLE = self::USER_STATE | self::PASSWORD_STATE | self::HOST_STATE | self::PORT_STATE; const RELATIVE_URL_WHOLE = self::PATH_STATE | self::QUERY_STATE | self::FRAGMENT_STATE; /** * current states */ protected int $authoritySate = self::AUTHORITY_WHOLE; protected int $relativeUrlState = self::RELATIVE_URL_WHOLE; protected bool $schemeState = true;
如果我们想损坏 $relativeUrlState
在 query
区域的状态,我们可以使用位运算符
$relativeUrlState &= ~Url::QUERY_STATE;
其余部分可以以类似的方式进行操作,除了 $schemeState
,它需要分配一个布尔值。
⚡ 创建您自己的策略示例
在构建您的 URL 更新过程时,有时您希望执行一个方法,该方法基于当前状态将不会执行。在这种情况下,使用额外的 forceUnlockMethod(...)
方法,您可以在某些部分中更改当前状态,从而强制系统执行所需的方法。
通过例子可以更好地理解这一点。让我们想象我们需要生成推广链接的URL。让我们制定一个策略,为所有具有another.site
域的URL添加一个等于40
的refid
参数。
策略代码
<?php namespace <your\namespace>; use Compass\DefaultUrlStrategy; use Compass\Url; class ReferralUrlStrategy extends DefaultUrlStrategy { private bool $isAllowInsertParam = false; /** * @inheritDoc */ public function updateQuery(array $items): string { if ($this->isAllowInsertParam) { $items['refid'] = 40; $this->isAllowInsertParam = false; } 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 { if ($items[Url::HOST] === 'another.site') { $this->isAllowInsertParam = true; } $relativeUrlState &= ~Url::QUERY_STATE; } }
现在让我们设置策略并输出两个URL,其中一个将是目的地,域名是another.site
$url = Url::createBlank(); $url->setUpdateStrategy(new ReferralUrlStrategy()); $url->setSource('https://another.site'); $url->updateSource(); echo $url->getSource(), '<br>'; # https://another.site/?refid=40 $url->setHost('vinograd.soft'); $url->updateSource(); echo $url->getSource(); # https://vinograd.soft
乍一看,似乎状态改变($relativeUrlState &= ~Url::QUERY_STATE;
)应该写在if
结构中,但这并不正确。在我们安装了vinograd.soft
主机后,调用updateSource()
方法不会导致我们的策略的updateQuery
方法的执行,因为没有添加任何参数以常规方式改变此部分的状态。因此,状态将保持不变,只有baseurl
部分将被更新,并且上次保存的refid=40
参数将与包含vinograd.soft
主机的新的baseurl
合并。
此示例表明,您不仅限于设置URL部分的常规方法。使用策略,您可以后处理结果,例如,当您需要为包含URL的HTML属性(href、src以及其他此类属性)转义结果时。
路径组件
👉 Compass\Path
可以描述为文件路径的对象表示。它在不依赖实际文件系统的情况下操作路径字符串。该组件,如Compass\Url
,有一个更新策略,包括一个updatePath()
方法。重要的是要注意,该组件是无状态的。
🚀方法演示
<?php use Compass\Path; require_once dirname(__DIR__, 1) . '/vendor/autoload.php'; $path = new Path('/__NAME__/__NAME__Scanner/__NAME2__Driver', '/'); $path->replaceAll([ '__NAME__' => 'User', '__NAME2__' => 'Filesystem', ]); $path->updateSource(); echo '<br>', $path; # /User/UserScanner/FilesystemDriver $path->setAll(['path', 'to', 'file.txt']); $path->updateSource(); echo '<br>', $path; # path/to/file.txt $path->set(1, 'newTo'); $path->updateSource(); echo '<br>', $path; # path/newTo/file.txt $path->setBy('path', 'newPath'); $path->updateSource(); echo '<br>', $path; # newPath/newTo/file.txt echo '<br>', $path->dirname(); # newPath/newTo $path->setSuffix('.v'); $path->updateSource(); echo '<br>', $path; # newPath/newTo/file.txt.v $path->setSource('newPath/newTo/file'); $path->setSuffix('.v'); $path->updateSource(); echo '<br>', $path; # newPath/newTo/file.v $path->replace('newPath','path'); $path->updateSource(); echo '<br>', $path; # path/newTo/file.v echo '<br>', $path->getLast(); # file.v
测试
php composer测试
贡献
有关详细信息,请参阅贡献指南。
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。