Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vinogradsoft/compass
:alien: :compass: A PHP library for conveniently managing URL components, offering features for easily processing hostnames, ports, schemes, and more, making it an intuitive solution for working with URLs in PHP-based applications.
https://github.com/vinogradsoft/compass
idn uri uri-builder uri-manipulations uri-parser uri-template url-builder url-creation url-modification url-retrieval
Last synced: 2 months ago
JSON representation
:alien: :compass: A PHP library for conveniently managing URL components, offering features for easily processing hostnames, ports, schemes, and more, making it an intuitive solution for working with URLs in PHP-based applications.
- Host: GitHub
- URL: https://github.com/vinogradsoft/compass
- Owner: vinogradsoft
- License: mit
- Created: 2023-10-14T22:57:25.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2023-12-03T02:18:32.000Z (about 1 year ago)
- Last Synced: 2024-10-13T18:08:40.019Z (3 months ago)
- Topics: idn, uri, uri-builder, uri-manipulations, uri-parser, uri-template, url-builder, url-creation, url-modification, url-retrieval
- Language: PHP
- Homepage:
- Size: 103 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README-ru_RU.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
Создавайте повторно используемые приложения.
Библиотека с открытым исходным кодом.
[![codecov](https://codecov.io/gh/vinogradsoft/compass/graph/badge.svg?token=S1XRZ1GEY8)](https://codecov.io/gh/vinogradsoft/compass)
## Что такое Compass?
> 👉 Compass - это библиотека, предназначенная для работы с URL-адресами и путями к файлам на жестком диске. В ее состав
> входят инструменты для упрощения манипуляций с этими данными. Цель библиотеки - облегчить работу с URL-адресами и
> данными о расположении файлов.## Общая информация
Compass может быть использован в различных PHP-приложениях для обработки путей к файлам и URL-адресов. Он включает в
себя два основных компонента: `Compass\Path` и `Compass\Url`. Оба этих компонента представляют собой отдельные объекты
и предлагают набор методов для простого манипулирования данными. `Compass\Path` предоставляет инструменты для работы с
директориями, включая поиск, замену и проверку наличия директорий в строке пути, а также изменение их порядка. В свою
очередь, `Compass\Url` обеспечивает возможности для работы с URL, позволяя создавать, получать и изменять различные
части URL-адреса.Оба компонента работают по схожему принципу, сначала собирают необходимые параметры, а затем применяют их к результату с
помощью специального метода `updateSource()`.## Установка
Предпочтительный способ установки - через [composer](http://getcomposer.org/download/).
Запустите команду
```
php composer require vinogradsoft/compass "^1.0"
```Требуется PHP 8.0 или новее.
## Компонент URL
### 🚀 Быстрый старт
```php
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 '
Authority: ', $url->getAuthority();
echo '
Base Url: ', $url->getBaseUrl();
echo '
Relative Url: ', $url->getRelativeUrl();
echo '
Absolute Url: ', $url->getSource(), '
';
echo '
Scheme: ', $url->getScheme();
echo '
User: ', $url->getUser();
echo '
Password: ', $url->getPassword();
echo '
Host: ', $url->getHost();
echo '
Port: ', $url->getPort();
echo '
Path: ', $url->getPath();
echo '
Suffix: ', $url->getSuffix();
echo '
Query: ', $url->getQuery();
echo '
Fragment: ', $url->getFragment();$url->setSource('http://россия.рф');
$url->setConversionIdnToAscii(true)->updateSource();
echo '
new URL: ',$url; #http://xn--h1alffa9f.xn--p1ai
```### Создание экземпляра класса Compass\Url
Объект класса `Compass\Url` может быть создан путем вызова статического метода `createBlank()`, либо с помощью
оператора `new`. Метод `createBlank` примечателен тем, что в своей работе применяет клонирование своего же
прототипа. У данного метода есть два необязательных параметра: `$isIdnToAscii`, `$updateStrategy` - они определяют,
будет ли происходить преобразование хоста в `punycode`, и какую стратегию обновления URL применять.Первый параметр, `$isIdnToAscii` - определяет необходимость преобразования хоста. Если он принимает значение `true`,
хост преобразуется, если же `false` - преобразование хоста не происходит.Второй параметр, `$updateStrategy` - определяет стратегию обновления URL. Стратегия включает в себя методы создания
составляющих URL-адреса.Чтобы создать новый экземпляр класса `Compass\Url` с помощью оператора `new` необходимо передать один
обязательный параметр - это исходный URL в виде строки.### Варианты сборки URL
Параметры можно устанавливать с помощью:
- конструктора
- метода `$url->setSource(string $src);`
- метода `$url->setAll(array $parts);`
- методов отвечающих за конкретную часть Url (как показано в быстром старте).### ⚡ Примеры
#### **👉 Через конструктор**
```php
$url = new Url('http://grigor:[email protected]:8080/path/to/resource?query=value#fragment');
```#### **👉 С помощью метода `$url->setSource(string $src);`**
```php
$url->setSource('http://grigor:[email protected]:8080/path/to/resource?query=value#fragment');
```#### **👉 С помощью метода `$url->setAll(array $parts);`**
```php
$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.**
```php
$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" и дорожной компанией которая за нее ответственна. В идеале дорога должна быть всегда ровная.
Когда на дороге повреждается какой-нибудь участок, например "С", ремонтная бригада выезжает на этот участок и
ремонтирует его. Так же можно представить и URL-адрес, где дорога это строка у которой есть логические части - участки.
Ремонтные бригады - это методы в стратегии обновления. Дорожная компания - это объект `Compass\Url`.У стратегии есть шесть методов в которых создаются части URL-адреса:
- `updateAuthority()`
- `updateBaseUrl()`
- `updateQuery()`
- `updatePath()`
- `updateRelativeUrl()`
- `updateAbsoluteUrl()`.Устанавливая какой-либо параметр для URL, система меняет состояние участка, как бы, повреждает тот
участок для которого был передан параметр. После вызова метода `$url->updateSource();` в работу включаются
соответствующие методы стратегии.> ❗ Важно запомнить, что в объекте `Compass\Url` хранятся исходные части, которые передал пользователь и результаты работы
> каждого метода стратегии.Выполнение методов можно поделить условно на три уровня.
```
УРОВЕНЬ 3
|--------------------------------updateAbsoluteUrl()---------------------------------|
| |
| УРОВЕНЬ 2 |
|---------------updateBaseUrl()-----------|------------updateRelativeUrl()-----------|
| | |
| УРОВЕНЬ 1 |
| updateAuthority() | updatePath() updateQuery() |
| /‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\|/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾‾‾\ |
|http://grigor:[email protected]: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` осуществляются битовыми операциями. Вот пример кода, который показывает их значения по умолчанию
когда состояние неповрежденное:```php
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`, то мы можем воспользоваться побитовыми
операторами:```php
$relativeUrlState &= ~Url::QUERY_STATE;
```Остальными участками можно манипулировать аналогичным способом, исключением является только `$schemeState` ему нужно
присвоить булево значение.### ⚡ Пример создания своей стратегии
При построении своего процесса обновления URL, иногда требуется, чтобы выполнился метод который на основе текущего
состояния не выполниться. В таких случаях используется дополнительный метод `forceUnlockMethod(...)` в котором можно
изменить текущее состояние определенного участка, тем самым заставить систему выполнить нужный метод.Это лучше понять на примере. Представим, что нам нужно генерировать URL для реферальных ссылок. Создадим стратегию в
которой будет добавляться для всех URL с доменом `another.site` параметр `refid` равный `40`.Код стратегии:
```php
;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`:
```php
$url = Url::createBlank();
$url->setUpdateStrategy(new ReferralUrlStrategy());$url->setSource('https://another.site');
$url->updateSource();
echo $url->getSource(), '
'; # 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` с прошлого раза, был бы склеен
с новым `baseurl` который содержит хост `vinograd.soft`.Этот пример показывает, что вы не ограничены только штатными методами установки частей URL. Используя стратегии можно
делать пост обработку результата, например когда нужно экранировать результат для HTML-атрибутов содержащих URL (href,
src и другие атрибуты этого типа).---
## Компонент PATH
👉 `Compass\Path` можно охарактеризовать как объектное представление пути к файлу. Он оперирует строкой пути не
опираясь на реальную файловую систему. Компонент так же как и `Compass\Url` имеет стратегию обновления, которая включает
в себя один метод `updatePath()`. Важно отметить, что этот компонент не имеет состояний.### 🚀 Демонстрация методов
```php
replaceAll([
'__NAME__' => 'User',
'__NAME2__' => 'Filesystem',
]);
$path->updateSource();echo '
', $path; # /User/UserScanner/FilesystemDriver$path->setAll(['path', 'to', 'file.txt']);
$path->updateSource();echo '
', $path; # path/to/file.txt$path->set(1, 'newTo');
$path->updateSource();echo '
', $path; # path/newTo/file.txt$path->setBy('path', 'newPath');
$path->updateSource();echo '
', $path; # newPath/newTo/file.txtecho '
', $path->dirname(); # newPath/newTo$path->setSuffix('.v');
$path->updateSource();
echo '
', $path; # newPath/newTo/file.txt.v$path->setSource('newPath/newTo/file');
$path->setSuffix('.v');
$path->updateSource();
echo '
', $path; # newPath/newTo/file.v$path->replace('newPath','path');
$path->updateSource();
echo '
', $path; # path/newTo/file.v
echo '
', $path->getLast(); # file.v
```## Тестировать
``` php composer tests ```
## Содействие
Пожалуйста, смотрите [ВКЛАД](CONTRIBUTING.md) для получения подробной информации.
## Лицензия
Лицензия MIT (MIT). Пожалуйста, смотрите [файл лицензии](LICENSE) для получения дополнительной информации.