20250724 1.2

[+] Добавлен новый тип GUID.

[*] В класс ObjectArray добавлена реализация интерфейсов IHashable, ISortable, IComparable.

[*] В класс Dictionary добавлена реализация интерфейсов IArrayable, IHashable, ISortable, IComparable.

[-] Класс GUIDExtension и все его методы помечены как устаревшие и скоро будут удалены.
This commit is contained in:
Александр Бабаев 2025-07-24 13:02:04 +03:00
parent f8f14244d0
commit 24bf2a009f
9 changed files with 639 additions and 439 deletions

View File

@ -4,8 +4,13 @@ namespace goodboyalex\php_components_pack\classes;
use ArrayAccess; use ArrayAccess;
use Countable; use Countable;
use goodboyalex\php_components_pack\interfaces\IArrayable;
use goodboyalex\php_components_pack\interfaces\IComparable;
use goodboyalex\php_components_pack\interfaces\IHashable;
use goodboyalex\php_components_pack\interfaces\ISerializable; use goodboyalex\php_components_pack\interfaces\ISerializable;
use goodboyalex\php_components_pack\interfaces\ISortable;
use goodboyalex\php_components_pack\traits\ArrayBasicTrait; use goodboyalex\php_components_pack\traits\ArrayBasicTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayComparableTrait;
use IteratorAggregate; use IteratorAggregate;
/** /**
@ -16,7 +21,8 @@ use IteratorAggregate;
* @version 1.0.3 * @version 1.0.3
* @since 1.0.14 * @since 1.0.14
*/ */
final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISerializable final class Dictionary
implements ArrayAccess, IteratorAggregate, Countable, ISerializable, IArrayable, IHashable, ISortable, IComparable
{ {
/** /**
* @var array $Container Контейнер. * @var array $Container Контейнер.
@ -26,33 +32,8 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
// Реализация наследуемых интерфейсов и классов // Реализация наследуемых интерфейсов и классов
use ArrayBasicTrait; use ArrayBasicTrait;
/** // Реализация интерфейса IComparable
* Добавление элементов в словарь. use ObjectArrayComparableTrait;
*
* @param array $dictionary Ассоциативный массив вида ключ => значение, который будет добавлен в словарь.
*
* @return void
*/
public function AddRange (array $dictionary): void
{
// Для каждого элемента массива
foreach ($dictionary as $key => $value)
// - добавляем его в словарь.
$this->Add($key, $value);
}
/**
* Добавление элемента в словарь.
*
* @param string $key Ключ.
* @param mixed $value Хранимое значение.
*
* @return void
*/
public function Add (string $key, mixed $value): void
{
$this->Container[$key] = $value;
}
/** /**
* Получение значения по ключу. * Получение значения по ключу.
@ -95,16 +76,6 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
return isset($this->Container[$key]); return isset($this->Container[$key]);
} }
/**
* Очистка всех элементов.
*
* @return void
*/
public function Clear (): void
{
$this->Container = [];
}
/** /**
* @inheritDoc * @inheritDoc
*/ */
@ -124,13 +95,77 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
} }
/** /**
* Сортирует внутренние данные по ключам. * @inheritDoc
* */
* @param bool $descending Сортировать ли данные в обратном порядке? public function ToArray (): array
{
return $this->Container;
}
/**
* @inheritDoc
*/
public function FromArray (array $array): void
{
// Очищаем словарь
$this->Clear();
// Добавляем элементы в словарь
$this->AddRange($array);
}
/**
* Очистка всех элементов.
* *
* @return void * @return void
*/ */
public function Sort (bool $descending = false): void public function Clear (): void
{
$this->Container = [];
}
/**
* Добавление элементов в словарь.
*
* @param array $dictionary Ассоциативный массив вида ключ => значение, который будет добавлен в словарь.
*
* @return void
*/
public function AddRange (array $dictionary): void
{
// Для каждого элемента массива
foreach ($dictionary as $key => $value)
// - добавляем его в словарь.
$this->Add($key, $value);
}
/**
* Добавление элемента в словарь.
*
* @param string $key Ключ.
* @param mixed $value Хранимое значение.
*
* @return void
*/
public function Add (string $key, mixed $value): void
{
$this->Container[$key] = $value;
}
/**
* @inheritDoc
*/
public function Hash (): string
{
return md5(json_encode($this->Container, JSON_UNESCAPED_UNICODE));
}
/**
* @inheritDoc
*
* @warning Свойство <code>$property</code> не используется.
*/
public function Sort (string $property = '', bool $descending = false): void
{ {
// Если задана сортировка по убыванию // Если задана сортировка по убыванию
if ($descending) if ($descending)
@ -142,12 +177,12 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
} }
/** /**
* Возвращает все элементы словаря в виде массива. * @inheritDoc
* *
* @return array Массив, содержащий все элементы словаря. * @warning Свойство <code>$propertyFunction</code> не используется.
*/ */
public function ToArray (): array public function SortCallback (callable $propertyFunction, bool $descending = false): void
{ {
return $this->Container; $this->Sort(descending: $descending);
} }
} }

View File

@ -5,9 +5,14 @@ namespace goodboyalex\php_components_pack\classes;
use ArrayAccess; use ArrayAccess;
use Countable; use Countable;
use goodboyalex\php_components_pack\interfaces\IArrayable; use goodboyalex\php_components_pack\interfaces\IArrayable;
use goodboyalex\php_components_pack\interfaces\IComparable;
use goodboyalex\php_components_pack\interfaces\IHashable;
use goodboyalex\php_components_pack\interfaces\ISerializable; use goodboyalex\php_components_pack\interfaces\ISerializable;
use goodboyalex\php_components_pack\interfaces\ISortable;
use goodboyalex\php_components_pack\traits\ArrayBasicTrait; use goodboyalex\php_components_pack\traits\ArrayBasicTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayComparableTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayConstantsTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayConstantsTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayHashableTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayLINQTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayLINQTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySearchAndSortTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySearchAndSortTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySerializeExTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySerializeExTrait;
@ -20,10 +25,11 @@ use IteratorAggregate;
* *
* @author Александр Бабаев * @author Александр Бабаев
* @package php_components_pack * @package php_components_pack
* @version 1.0.6 * @version 1.1
* @since 1.0 * @since 1.0
*/ */
final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, ISerializable, IArrayable final class ObjectArray
implements ArrayAccess, IteratorAggregate, Countable, ISerializable, IArrayable, IHashable, ISortable, IComparable
{ {
/** /**
* @var array $Container Массив объектов, хранящихся в данном классе. * @var array $Container Массив объектов, хранящихся в данном классе.
@ -51,6 +57,12 @@ final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, IS
// Реализация методов интерфейса IArrayable // Реализация методов интерфейса IArrayable
use ObjectArrayToArrayTrait; use ObjectArrayToArrayTrait;
// Реализация методов интерфейса IHashable
use ObjectArrayHashableTrait;
// Реализация методов интерфейса IComparable
use ObjectArrayComparableTrait;
/** /**
* Конструктор класса. * Конструктор класса.
* *

View File

@ -0,0 +1,155 @@
<?php
namespace goodboyalex\php_components_pack\extensions;
use Deprecated;
use Random\RandomException;
/**
* Расширение Guid.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.0
* @deprecated 1.2
*
*/
final class GUIDExtension
{
/**
* Пустой Guid.
*/
#[Deprecated('GUIDExtension устарел, пожалуйста используйте класс GUID / GUIDExtension is deprecated, please use class GUID / GUIDExtension', '1.2')]
public const string GUIDEmpty = "00000000-0000-0000-0000-000000000000";
/**
* Генерирует Guid.
*
* @return string Сгенерированный Guid.
*/
#[Deprecated('GUIDExtension устарел, пожалуйста используйте класс GUID / GUIDExtension is deprecated, please use class GUID / GUIDExtension', '1.2')]
public static function Generate (): string
{
// Цикл создания Guid
do
$guid = self::DoGenerate();
// - пока Guid не будет корректен
while (!self::Validate($guid));
// Возвращаем Guid
return $guid;
}
/**
* Генерирует Guid.
*
* @return string Сгенерированный Guid.
*/
#[Deprecated('GUIDExtension устарел, пожалуйста используйте класс GUID / GUIDExtension is deprecated, please use class GUID / GUIDExtension', '1.2')]
private static function DoGenerate (): string
{
try {
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
random_int(0, 0xffff),
random_int(0, 0xffff),
// 16 bits for "time_mid"
random_int(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
random_int(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
random_int(0, 0x3fff) | 0x8000,
// 48 bits for "node"
random_int(0, 0xffff),
random_int(0, 0xffff),
random_int(0, 0xffff)
);
}
catch (RandomException) {
return self::GUIDEmpty;
}
}
/**
* Проверяет Guid на корректность.
*
* @param string|null $str Guid на проверку
*
* @return bool Корректен ли Guid.
*/
#[Deprecated('GUIDExtension устарел, пожалуйста используйте класс GUID / GUIDExtension is deprecated, please use class GUID / GUIDExtension', '1.2')]
public static function Validate (?string $str): bool
{
// Если Guid пустой
if (StringExtension::IsNullOrWhitespace($str))
// - возвращаем false
return false;
// Проверяем длину
$isLenCorrect = strlen($str) == 36;
// Если длина не корректна
if (!$isLenCorrect)
// - возвращаем false
return false;
// Разбиваем на части
$explodedStr = explode("-", $str);
// Если количество частей не равно 5
if (count($explodedStr) !== 5)
// - возвращаем false
return false;
// Проверяем длину каждой части
// - первая часть должна быть длиной 8 символов
if (strlen($explodedStr[0]) !== 8)
// -- возвращаем false
return false;
// - вторая часть должна быть длиной 4 символа
if (strlen($explodedStr[1]) !== 4)
// -- возвращаем false
return false;
// - третья часть должна быть длиной 4 символа
if (strlen($explodedStr[2]) !== 4)
// -- возвращаем false
return false;
// - четвертая часть должна быть длиной 4 символа
if (strlen($explodedStr[3]) !== 4)
// -- возвращаем false
return false;
// - пятая часть должна быть длиной 12 символов
if (strlen($explodedStr[4]) !== 12)
// -- возвращаем false
return false;
// Проверка пройдена
return true;
}
/**
* Проверяет Guid на пустоту.
*
* @param string|null $str Guid на проверку
*
* @return bool Пустой ли GUID
*/
#[Deprecated('GUIDExtension устарел, пожалуйста используйте класс GUID / GUIDExtension is deprecated, please use class GUID / GUIDExtension', '1.2')]
public static function IsNotValidOrEmpty (?string $str): bool
{
return !self::Validate($str) || $str == self::GUIDEmpty;
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace goodboyalex\php_components_pack\traits\ObjectArray;
/**
* Часть кода класса ObjectArray, отвечающая за реализацию интерфейса IComparable.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.2
*/
trait ObjectArrayComparableTrait
{
/**
* @inheritDoc
*/
public function CompareTo (mixed $other): int
{
// Сравниваем на равенство
if ($this->IsEqualsTo($other))
// - если равны, то возвращаем 0
return 0;
// Возвращаем результат сравнения количества элементов
return $this->Count() > $other->Count() ? 1 : -1;
}
/**
* @inheritDoc
*/
public function IsEqualsTo (mixed $other): bool
{
// Получаем хэши
// - этого объекта
$thisHash = $this->Hash();
// - переданного объекта
$otherHash = $other->Hash();
// Сравниваем хэши и возвращаем результат
return $thisHash == $otherHash;
}
/**
* @inheritDoc
*/
public function CompareByProperty (string $propertyName, mixed $other): int
{
// Получаем значения свойств
// - этого объекта
$thisProperty = $this->GetColumn($propertyName);
// - переданного объекта
$otherProperty = $other->GetColumn($propertyName);
// Сравниваем их по количеству
if (count($thisProperty) !== count($otherProperty))
// - если количество элементов не совпадает, то возвращаем результат
return count($thisProperty) > count($otherProperty) ? 1 : -1;
// Переменная для хранения результата
$delta = 0;
// Проходимся по массивам
for ($i = 0; $i < count($thisProperty); $i++) {
// - получаем значения
// -- текущего массива
$thisValue = $thisProperty[$i];
// -- переданного массива
$otherValue = $otherProperty[$i];
// - если значения равны
if ($thisValue === $otherValue)
// - то пропускаем элемент
continue;
// - иначе сравниваем
if ($thisValue > $otherValue)
// - если текущее значение больше, то увеличиваем счетчик
$delta++;
else
// - иначе уменьшаем счетчик
$delta--;
}
// Возвращаем результат
return $delta === 0 ? 0 : ($delta > 0 ? 1 : -1);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace goodboyalex\php_components_pack\traits\ObjectArray;
use goodboyalex\php_components_pack\interfaces\IArrayable;
use goodboyalex\php_components_pack\interfaces\IHashable;
use goodboyalex\php_components_pack\interfaces\ISerializable;
/**
* Часть кода класса ObjectArray, отвечающая за реализацию интерфейса IHashable.
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0
* @since 1.2
*/
trait ObjectArrayHashableTrait
{
/**
* @inheritDoc
*/
public function Hash (): string
{
// Создаю массив хешей всех объектов
$toHash = [];
// Перебираю все объекты в массиве
foreach ($this->Container as $object) {
// - если объект реализует интерфейс IHashable
if ($object instanceof IHashable) {
// -- то хэширую его и добавляю в массив
$toHash[] = $object->Hash();
// -- переходим к следующему элементу
continue;
}
// - если объект реализует интерфейс ISerializable
if ($object instanceof ISerializable) {
// -- то сериализую его и добавляю в массив
$toHash[] = $object->Serialize();
// -- переходим к следующему элементу
continue;
}
// - если объект реализует интерфейс IArrayable
if ($object instanceof IArrayable) {
// -- то преобразую его в массив
$array = $object->ToArray();
// -- сериализую его и добавляю в массив
$toHash[] = json_encode($array, JSON_UNESCAPED_UNICODE);
// -- переходим к следующему элементу
continue;
}
// - иначе просто сериализую объект
$toHash[] = serialize($object);
}
// Возвращаю хеш массива
return md5(json_encode($toHash, JSON_UNESCAPED_UNICODE));
}
}

View File

@ -63,12 +63,12 @@ trait ObjectArraySearchAndSortTrait
/** /**
* Сортирует массив объектов, по значению свойства объекта. * Сортирует массив объектов, по значению свойства объекта.
* *
* @param string $objectProperty Имя свойства объекта * @param string $property Имя свойства объекта
* @param bool $descending Направление сортировки * @param bool $descending Направление сортировки
* *
* @return void * @return void
*/ */
public function Sort (string $objectProperty, bool $descending = false): void public function Sort (string $property = '', bool $descending = false): void
{ {
// Создаём результирующий массив // Создаём результирующий массив
$result = array_merge($this->Container, []); $result = array_merge($this->Container, []);
@ -77,8 +77,8 @@ trait ObjectArraySearchAndSortTrait
usort($result, usort($result,
fn ($a, $b) fn ($a, $b)
=> !$descending => !$descending
? $a->$objectProperty <=> $b->$objectProperty ? $a->$property <=> $b->$property
: $b->$objectProperty <=> $a->$objectProperty); : $b->$property <=> $a->$property);
// Присваиваем результат // Присваиваем результат
$this->Container = $result; $this->Container = $result;

View File

@ -40,7 +40,7 @@
### Перевод в строку. ### Перевод в строку.
За перевод в строку отвечают 2 метода: «магический метод» `__toString` и `ToString`. За перевод в строку отвечают 3 метода: «магический метод» `__toString`, `ToString` и `Segment`.
#### «Магический метод» `__toString` #### «Магический метод» `__toString`
@ -82,6 +82,83 @@
00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000
#### Метод `Segment`
Этот метод возвращает сегмент GUID по его номеру. Он имеет **1 обязательный параметр** - номер сегмента
`int $segmentNumber`.
Метод возвращает `string` - строковое представление сегмента GUID.
**ВАЖНО:** значение `$segmentNumber` должно быть от 1 до 5 включительно. В противном случае выбросится исключение
`OutOfRangeException`.
Синтаксис:
public function Segment (int $segmentNumber): string
**Пример:**
// Создаю пустой GUID
$guid = new GUID ('00000000-0000-0000-0000-000000000000');
// Вывожу его 1 сегмент
echo $guid->Segment(1);
// С новой строки
echo '<br>';
// Ошибка
try {
echo $guid->Segment(0);
} catch (OutOfRangeException $e) {
echo $e->getMessage();
}
В результате, на экране появится:
00000000
Номер сегмента должен быть между 1 и 5 / Segment number must be between 1 and 5.
### Перевод из строки.
За перевод из строки отвечают 2 метода: конструктор и `Parse`.
#### Метод `Parse`
Этот статический метод переводит строку в GUID. Он принимает только **1 обязательный параметр** - строковое
представление
GUID `string $guidString` и **1 необязательный параметр** - действие при некорректном GUID `bool $emptyIfNotValid`:
`true` - вернётся пустой GUID, `false` - выбросится исключение типа `InvalidArgumentException`, который по умолчанию
выбрасывает исключение.
Метод возвращает объект класса `GUID`, полученный из строкового представления.
**ВАЖНО:** может выбрасываться исключение `InvalidArgumentException` при некорректном GUID и отключённом параметре
`$emptyIfNotValid`.
Синтаксис:
public static function Parse (string $guidString, bool $emptyIfNotValid = false): GUID
**Пример:**
// Создаю пустой GUID
$guid1 = GUID::Parse ('00000000-0000-0000-0000-000000000000', true);
// Вывожу его
echo "guid1 = $guid1";
// Разделитель
echo '<br>';
try {
// Создаю из ошибочного GUID
$guid2 = GUID::Parse('ЭТО ОШИБКА!!!')
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
В результате, на экране появится:
00000000-0000-0000-0000-000000000000
Предан неверный GUID / Wrong GUID.
### Работа с массивом байтов ### Работа с массивом байтов
Для преобразования GUID в массив байтов и обратно используется 2 метода: `ToBytes` и `FromBytes`. Для преобразования GUID в массив байтов и обратно используется 2 метода: `ToBytes` и `FromBytes`.
@ -153,392 +230,109 @@
00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000
#### Метод `ReadInt` ### Генерация GUID
Это метод, который читает значение ключа JSON. Он имеет **1 обязательный параметр** `string $key` (ключ) и **1 За генерацию GUID отвечает статический метод `Generate`. Это метод не имеет параметров и возвращает сгенерированный
необязательный параметр** `int $default` (значение по умолчанию, задан по умолчанию в `0`). GUID.
Этот метод возвращает `int`: значение ключа JSON или значение по умолчанию.
Синтаксис: Синтаксис:
public function ReadInt (string $key, int $default = 0): int public static function Generate (): GUID
#### Метод `ReadFloat`
Это метод, который читает значение ключа JSON. Он имеет **1 обязательный параметр** `string $key` (ключ) и **1
необязательный параметр** `float $default` (значение по умолчанию, задан по умолчанию в `0.0`).
Этот метод возвращает `float`: значение ключа JSON или значение по умолчанию.
Синтаксис:
public function ReadFloat (string $key, float $default = 0.0): float
#### Метод `ReadBool`
Это метод, который читает значение ключа JSON. Он имеет **1 обязательный параметр** `string $key` (ключ) и **1
необязательный параметр** `bool $default` (значение по умолчанию, задан по умолчанию в `false`).
Этот метод возвращает `bool`: значение ключа JSON или значение по умолчанию.
Синтаксис:
public function ReadBool (string $key, bool $default = false): bool
#### Метод `ReadArray`
Это метод, который читает значение ключа JSON. Он имеет **1 обязательный параметр** `string $key` (ключ) и **1
необязательный параметр** `array $default` (значение по умолчанию, задан по умолчанию в `[]`).
Этот метод возвращает `array`: значение ключа JSON или значение по умолчанию.
Синтаксис:
public function ReadArray (string $key, array $default = []): array
#### Метод `ReadObject`
Это метод, который читает значение ключа JSON. Он имеет **2 обязательных параметра**:
- `string $key` (ключ);
- `object $default` (значение по умолчанию).
Этот метод возвращает `object`: значение ключа JSON или значение по умолчанию.
Синтаксис:
public function ReadObject (string $key, object $default): object
#### Метод `ReadSerializable`
Это метод, который читает значение ключа JSON. Он имеет **2 обязательных параметра**:
- `string $key` (ключ);
- `string $serializableClassName` (имя класса, реализующего интерфейс ISerializable, с namespace).
Этот метод возвращает класс, реализующий интерфейс `ISerializable`.
**Важно!** Этот метод может выбросить исключение `JsonException`, если класс, заданный в `$serializableClassName` не
реализует интерфейс `ISerializable`.
Синтаксис:
public function ReadSerializable (string $key, string $serializableClassName): ISerializable
**Пример,** **Пример,**
Пусть для примера, класс `Demo` из namespace `iam\namespace` реализует интерфейс `ISerializable`. // Создаю GUID
$guid = GUID::Generate ();
// Выводим
echo $guid;
// Создаю класс В результате, например, на экране появится:
$json = new JsonReWriter();
// ... Здесь где-то загрузка данных
// Получаю класс
try {
/**
* @var Demo $unSerializableClass
*/
$unSerializableClass = $json->ReadSerializable("test", "iam\\namespace\\Demo");
} catch (JsonException $e) {
echo $e->getMessage();
}
В результате, переменная `$unSerializableClass` будет содержать данные класса `Demo`. 5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1
### Запись данных ### Валидация GUID
Для чтения данных используется один общий метод `Write` и 3 его производных метода: `WriteArray`, `WriteObject` и Для валидации GUID используется 2 метода: `Validate` и `isInvalidOrEmpty`.
`WriteSerializable`.
**Важно!** Лобой из вышеуказанных методов может выбросить исключение `JsonException`, если ключ не содержит вложений, #### Метод `Validate`
хотя от него требуется обратное.
#### Метод `Write` Это статичный метод проверяет корректность GUID. Он имеет только **1 параметр** - объект GUID или его строковое представление для проверки `GUID|null|string $guid`.
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**: Этот метод возвращает `bool`: результат проверки.
- `string $key` (ключ);
- `mixed $value` (записываемое значение).
Этот метод ничего не возвращает.
Синтаксис: Синтаксис:
public function Write (string $key, mixed $value): void public static function Validate (string|GUID|null $guid): bool
**Пример,** **Пример,**
// Имя файла // Валидация класса GUID
$fileName = __DIR__ . "/test.json"; echo GUID::Validate(new GUID ('00000000-0000-0000-0000-000000000000')) ? 'GUID верен' : 'GUID ошибочен';
// Создаём класс
$json = new JsonReWriter();
// Заполним данными
try {
$json->Write("test/subtest/AAA", "123");
$json->Write("test/subtest/BBB", 1.23);
$json->Write("test1/test", 123);
$json->Write("test2/test", true);
$json->WriteArray("test3/test/res", [1, 2, 3]);
} catch (JsonException $e) {
echo $e->getMessage();
}
// Сохраняем созданный JSON файл
$json->SaveToFile($fileName);
Содержимое файла `test.json` представлено далее: // Разделитель
echo '<br>';
{ // Валидация строки
"test": { echo GUID::Validate('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1') ? 'GUID верен' : 'GUID ошибочен';
"subtest": {
"AAA": "123", // Разделитель
"BBB": 1.23 echo '<br>';
}
},
"test1": {
"test": 123
},
"test2": {
"test": true
},
"test3": {
"test": {
"res": "[1,2,3]"
}
}
}
#### Метод `WriteArray` // Валидация ошибки
echo GUID::Validate('НЕ GUID') ? 'GUID верен' : 'GUID ошибочен';
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**: В результате, на экране появится:
- `string $key` (ключ); GUID верен
- `array $array` (записываемое значение). GUID верен
GUID ошибочен
Этот метод ничего не возвращает. #### Метод `isInvalidOrEmpty`
Это статический метод, который проверяет объекты GUID на корректность и на «пустое» значение. Он имеет только **1 параметр** - объект GUID или `null` для проверки `?GUID $guid`.
Этот метод возвращает `bool`: результат проверки GUID.
Синтаксис: Синтаксис:
public function WriteArray (string $key, array $array): void public static function isInvalidOrEmpty (?GUID $guid): bool
#### Метод `WriteObject`
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**:
- `string $key` (ключ);
- `object $value` (записываемое значение).
Этот метод ничего не возвращает.
Синтаксис:
public function WriteObject (string $key, object $value): void
#### Метод `WriteSerializable`
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**:
- `string $key` (ключ);
- `ISerializable $serializableValue` (записываемое значение).
Этот метод ничего не возвращает.
Синтаксис:
public function WriteSerializable (string $key, ISerializable $serializableValue): void
**Пример,**
Пусть для примера, класс `Demo` из namespace `iam\namespace` реализует интерфейс `ISerializable`.
// Имя файла
$fileName = __DIR__ . "/test.json";
// Создаём класс
$json = new JsonReWriter();
// Создаём класс Demo
$serializableClass = new Demo(...);
// Заполним данными
try {
$json->WriteSerializable("test", $serializableClass);
} catch (JsonException $e) {
echo $e->getMessage();
}
...
### Работа с ключами JSON
Для работы с ключами JSON есть 2 метода: `IsKeyExists` и `GetKeys`.
#### Метод `IsKeyExists`
Это метод проверяем наличие ключа в JSON. Он имеет **1 обязательный параметр** - `string $key` (ключ).
Этот метод возвращает `bool`: `true` если ключ найден и `false` в противном случае.
Синтаксис:
public function IsKeyExists (string $key): bool
**Пример,** **Пример,**
// Создаём класс // Валидация класса GUID
$json = new JsonReWriter(); echo GUID::isInvalidOrEmpty(new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1')) ? 'GUID верен' : 'GUID ошибочен';
// Заполним данными
try {
$json->Write("test/subtest/AAA", "123");
$json->Write("test/subtest/BBB", 1.23);
$json->Write("test1/test", 123);
$json->Write("test2/test", true);
$json->WriteArray("test3/test/res", [1, 2, 3]);
} catch (JsonException $e) {
echo $e->getMessage();
}
// Проверяем ключи
$check1 = $json->IsKeyExists("test/subtest/AAA");
$check2 = $json->IsKeyExists("test/subtest/ССС");
В результате, `$check1` будет `true`, а `$check2` - `false`. // Разделитель
echo '<br>';
#### Метод `GetKeys` // Валидация пустого GUID
echo GUID::isInvalidOrEmpty('00000000-0000-0000-0000-000000000000') ? 'GUID верен' : 'GUID ошибочен';
// Разделитель
echo '<br>';
Это метод получает список ключей. Он имеет **2 необязательных параметра**: // Валидация null
echo GUID::isInvalidOrEmpty(null) ? 'GUID верен' : 'GUID ошибочен';
- `string $parentKey` (ключ родителя (или "" (установлено по умолчанию) для всех); В результате, на экране появится:
- `bool $includeChildren` (нужно ли включать дочерние ключи (по умолчанию, да)).
Этот метод возвращает `array`: список ключей. GUID верен
GUID ошибочен
GUID ошибочен
### Пустой GUID
За получение пустого GUID отвечает статический метод `Empty`. Это метод не имеет параметров и возвращает пустой GUID (`00000000-0000-0000-0000-000000000000`)
Синтаксис: Синтаксис:
public function GetKeys (string $parentKey = "", bool $includeChildren = true): array public static function Empty (): GUID
**Пример,** **Пример,**
// Создаём класс // Выводим
$json = new JsonReWriter(); echo GUID::Empty();
// Заполним данными
try {
$json->Write("test/subtest/AAA", "123");
$json->Write("test/subtest/BBB", 1.23);
$json->Write("test1/test", 123);
$json->Write("test2/test", true);
$json->WriteArray("test3/test/res", [1, 2, 3]);
} catch (JsonException $e) {
echo $e->getMessage();
}
// Получаем ключи
$keys1 = $json->GetKeys("test");
$keys2 = $json->GetKeys("test", false);
$keys3 = $json->GetKeys();
В результате, `$key1` будет следующим массивом: В результате, на экране появится:
[ 00000000-0000-0000-0000-000000000000
"test/subtest",
"test/subtest/AAA",
"test/subtest/BBB"
]
`$key2` будет следующим массивом:
[
"subtest"
]
`$key3` будет следующим массивом:
[
"test",
"test/subtest",
"test/subtest/AAA",
"test/subtest/BBB",
"test1",
"test1/test",
"test2",
"test2/test",
"test3",
"test3/test",
"test3/test/res"
]
### Удаление ключей JSON
Для удаления ключей JSON есть 2 метода: `DeleteKey`, который удаляет только определённый ключ и `Clear`, который удаляет
**все ключи** из json-файла.
#### Метод `DeleteKey`
Это метод удаляет только определённый ключ в JSON. Он имеет **1 обязательный параметр** - `string $key` (ключ).
Этот метод возвращает `bool` - результат удаления ключа: `true` - удаление прошло успешно, `false` - произошла ошибка
при удалении.
Синтаксис:
public function DeleteKey (string $key): bool
**Пример,**
// Создаём класс
$json = new JsonReWriter();
// Заполним данными
try {
$json->Write("test/subtest/AAA", "123");
$json->Write("test/subtest/BBB", 1.23);
$json->Write("test1/test", 123);
$json->Write("test2/test", true);
$json->WriteArray("test3/test/res", [1, 2, 3]);
} catch (JsonException $e) {
echo $e->getMessage();
}
// Получаемем ключи до удаления
$check1 = $json->GetKeys("test/subtest");
// Удаляем ключ
$this->DeleteKey("test/subtest/BBB");
// Получаемем ключи после удаления
$check2 = $json->GetKeys("test/subtest");
В результате, `$check1` будет
[
"test/subtest",
"test/subtest/AAA",
"test/subtest/BBB"
]
а `$check2`:
[
"test/subtest",
"test/subtest/AAA"
]
#### Метод `Clear`
Это метод удаляет **все ключи** из json-файла. Он не имеет никаких параметров и ничего не возвращает.
Синтаксис:
public function Clear (): void
**Пример,**
// Создаём класс
$json = new JsonReWriter();
// Заполним данными
try {
$json->Write("test/subtest/AAA", "123");
$json->Write("test/subtest/BBB", 1.23);
$json->Write("test1/test", 123);
$json->Write("test2/test", true);
$json->WriteArray("test3/test/res", [1, 2, 3]);
} catch (JsonException $e) {
echo $e->getMessage();
}
// Очищаем
$json->Clear();
// Получаем ключи
$keys = $json->GetKeys();
В результате, `$key` будет следующим массивом:
[
]

View File

@ -61,34 +61,6 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
$this->Value = $value; $this->Value = $value;
} }
/**
* Возвращает пустой GUID.
*
* @return GUID Пустой GUID.
*/
public static function Empty (): GUID
{
return new GUID();
}
// Подключаем трейт реализующий интерфейс ISerializable
use GUIDSerializeTrait;
// Подключаем трейт реализующий интерфейс IArrayable
use GUIDArrayableTrait;
// Подключаем трейт реализующий интерфейс IDuplicated
use GUIDDuplicatedTrait;
// Подключаем трейт реализующий интерфейс JsonSerializable
use GUIDJsonSerializableTrait;
// Подключаем трейт реализующий интерфейс IHashable
use GUIDHashableTrait;
// Подключаем трейт реализующий интерфейс IComparable
use GUIDComparableTrait;
/** /**
* Генерация нового случайного GUID. * Генерация нового случайного GUID.
* *
@ -129,6 +101,24 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
return new self($guid); return new self($guid);
} }
// Подключаем трейт реализующий интерфейс ISerializable
use GUIDSerializeTrait;
// Подключаем трейт реализующий интерфейс IArrayable
use GUIDArrayableTrait;
// Подключаем трейт реализующий интерфейс IDuplicated
use GUIDDuplicatedTrait;
// Подключаем трейт реализующий интерфейс JsonSerializable
use GUIDJsonSerializableTrait;
// Подключаем трейт реализующий интерфейс IHashable
use GUIDHashableTrait;
// Подключаем трейт реализующий интерфейс IComparable
use GUIDComparableTrait;
/** /**
* Проверяет, является ли GUID пустым или недействительным. * Проверяет, является ли GUID пустым или недействительным.
* *
@ -138,17 +128,17 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
*/ */
public static function isInvalidOrEmpty (?GUID $guid): bool public static function isInvalidOrEmpty (?GUID $guid): bool
{ {
return !self::Validate($guid) || $guid === self::EMPTY; return !self::Validate($guid) || $guid->IsEqualsTo(self::Empty());
} }
/** /**
* Валидирует строку GUID. * Валидирует строку GUID.
* *
* @param mixed $guid Объект GUID или строка для проверки. * @param string|GUID|null $guid Объект GUID или его строковое представление для проверки.
* *
* @return bool Результат проверки. * @return bool Результат проверки.
*/ */
public static function Validate (mixed $guid): bool public static function Validate (string|GUID|null $guid): bool
{ {
// Проверка на пустое значение // Проверка на пустое значение
if (empty($guid)) if (empty($guid))
@ -164,6 +154,16 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
return preg_match('/^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$/', $guid) > 0; return preg_match('/^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$/', $guid) > 0;
} }
/**
* Возвращает пустой GUID.
*
* @return GUID Пустой GUID.
*/
public static function Empty (): GUID
{
return new GUID();
}
/** /**
* Создает экземпляр GUID из массива байтов. * Создает экземпляр GUID из массива байтов.
* *
@ -193,19 +193,26 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
/** /**
* Создает экземпляр GUID из строки GUID. * Создает экземпляр GUID из строки GUID.
* *
* @param string $guidString Строка GUID. * @param string $guidString Строковое представление GUID.
* @param bool $emptyIfNotValid Если GUID недействителен, возвращать пустой GUID или выбрасывать исключение. По
* умолчанию: выбрасывать исключение.
* *
* @return GUID Класс GUID. * @return GUID Экземпляр GUID.
*/ */
public static function Parse (string $guidString): GUID public static function Parse (string $guidString, bool $emptyIfNotValid = false): GUID
{ {
return // Проверка на валидность GUID
// Проверка на валидность переданного GUID if (self::Validate($guidString))
!self::Validate($guidString) // - если GUID действителен, возвращаем экземпляр GUID
// - если GUID недействителен, выбрасываем исключение return new GUID($guidString);
? throw new InvalidArgumentException('Предан неверный GUID / Wrong GUID.')
// - иначе, создаем экземпляр GUID из строки // Если же GUID недействителен и запрещено выбрасывать исключение
: new GUID($guidString); if ($emptyIfNotValid)
// -- то возвращаем пустой GUID
return self::Empty();
else
// -- иначе выбрасываем исключение
throw new InvalidArgumentException('Предан неверный GUID / Wrong GUID.');
} }
/** /**

View File

@ -3,6 +3,8 @@
namespace goodboyalex\php_components_pack\tests\types; namespace goodboyalex\php_components_pack\tests\types;
use goodboyalex\php_components_pack\types\GUID; use goodboyalex\php_components_pack\types\GUID;
use InvalidArgumentException;
use OutOfRangeException;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class GUIDTest extends TestCase class GUIDTest extends TestCase
@ -28,26 +30,57 @@ class GUIDTest extends TestCase
public function testSegment () public function testSegment ()
{ {
$this->PrepareForTest();
$guid = new GUID ('00000000-0000-0000-0000-000000000000');
$this->assertEquals('00000000', $guid->Segment(1));
$this->expectException(OutOfRangeException::class);
$guid->Segment(0);
} }
public function testToString () public function testToString ()
{ {
$this->PrepareForTest();
$guid = new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1');
$this->assertEquals('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1', $guid->ToString());
} }
public function testIsInvalidOrEmpty () public function testIsInvalidOrEmpty ()
{ {
$this->PrepareForTest();
$this->assertFalse(GUID::isInvalidOrEmpty(new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1')));
$this->assertTrue(GUID::isInvalidOrEmpty(new GUID ('00000000-0000-0000-0000-000000000000')));
$this->assertTrue(GUID::isInvalidOrEmpty(null));
} }
public function testParse () public function testParse ()
{ {
$this->PrepareForTest();
$guid = new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1');
$parsed = GUID::Parse('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1', true);
$this->assertTrue($guid->IsEqualsTo($parsed));
$this->expectException(InvalidArgumentException::class);
GUID::Parse('НЕ GUID');
} }
public function test__toString () public function test__toString ()
{ {
$this->PrepareForTest();
$guid = new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1');
$str = "$guid";
$this->assertEquals('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1', $str);
} }
public function testToBytes () public function testToBytes ()
@ -80,11 +113,17 @@ class GUIDTest extends TestCase
public function testGenerate () public function testGenerate ()
{ {
$this->PrepareForTest();
$guid = GUID::Generate();
self::assertFalse(GUID::isInvalidOrEmpty($guid));
} }
public function testFromBytes () public function testFromBytes ()
{ {
$this->PrepareForTest();
// Создаю массив // Создаю массив
$array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; $array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@ -93,11 +132,14 @@ class GUIDTest extends TestCase
// И вывожу его // И вывожу его
self::assertEquals('00000000-0000-0000-0000-000000000000', $guid->ToString()); self::assertEquals('00000000-0000-0000-0000-000000000000', $guid->ToString());
} }
public function testValidate () public function testValidate ()
{ {
$this->PrepareForTest();
$this->assertTrue(GUID::Validate(new GUID ('00000000-0000-0000-0000-000000000000')));
$this->assertTrue(GUID::Validate('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1'));
$this->assertFalse(GUID::Validate('НЕ GUID'));
} }
} }