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 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\ISortable;
use goodboyalex\php_components_pack\traits\ArrayBasicTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayComparableTrait;
use IteratorAggregate;
/**
@ -16,7 +21,8 @@ use IteratorAggregate;
* @version 1.0.3
* @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 Контейнер.
@ -26,33 +32,8 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
// Реализация наследуемых интерфейсов и классов
use ArrayBasicTrait;
/**
* Добавление элементов в словарь.
*
* @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;
}
// Реализация интерфейса IComparable
use ObjectArrayComparableTrait;
/**
* Получение значения по ключу.
@ -95,16 +76,6 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
return isset($this->Container[$key]);
}
/**
* Очистка всех элементов.
*
* @return void
*/
public function Clear (): void
{
$this->Container = [];
}
/**
* @inheritDoc
*/
@ -124,13 +95,77 @@ final class Dictionary implements ArrayAccess, IteratorAggregate, Countable, ISe
}
/**
* Сортирует внутренние данные по ключам.
*
* @param bool $descending Сортировать ли данные в обратном порядке?
* @inheritDoc
*/
public function ToArray (): array
{
return $this->Container;
}
/**
* @inheritDoc
*/
public function FromArray (array $array): void
{
// Очищаем словарь
$this->Clear();
// Добавляем элементы в словарь
$this->AddRange($array);
}
/**
* Очистка всех элементов.
*
* @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)
@ -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 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\ISortable;
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\ObjectArrayHashableTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayLINQTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySearchAndSortTrait;
use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySerializeExTrait;
@ -20,10 +25,11 @@ use IteratorAggregate;
*
* @author Александр Бабаев
* @package php_components_pack
* @version 1.0.6
* @version 1.1
* @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 Массив объектов, хранящихся в данном классе.
@ -51,6 +57,12 @@ final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, IS
// Реализация методов интерфейса IArrayable
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 Направление сортировки
*
* @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, []);
@ -77,8 +77,8 @@ trait ObjectArraySearchAndSortTrait
usort($result,
fn ($a, $b)
=> !$descending
? $a->$objectProperty <=> $b->$objectProperty
: $b->$objectProperty <=> $a->$objectProperty);
? $a->$property <=> $b->$property
: $b->$property <=> $a->$property);
// Присваиваем результат
$this->Container = $result;

View File

@ -40,7 +40,7 @@
### Перевод в строку.
За перевод в строку отвечают 2 метода: «магический метод» `__toString` и `ToString`.
За перевод в строку отвечают 3 метода: «магический метод» `__toString`, `ToString` и `Segment`.
#### «Магический метод» `__toString`
@ -82,6 +82,83 @@
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`.
@ -153,392 +230,109 @@
00000000-0000-0000-0000-000000000000
#### Метод `ReadInt`
### Генерация GUID
Это метод, который читает значение ключа JSON. Он имеет **1 обязательный параметр** `string $key` (ключ) и **1
необязательный параметр** `int $default` (значение по умолчанию, задан по умолчанию в `0`).
Этот метод возвращает `int`: значение ключа JSON или значение по умолчанию.
За генерацию GUID отвечает статический метод `Generate`. Это метод не имеет параметров и возвращает сгенерированный
GUID.
Синтаксис:
public function ReadInt (string $key, int $default = 0): int
#### Метод `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
public static function Generate (): GUID
**Пример,**
Пусть для примера, класс `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` и
`WriteSerializable`.
Для валидации GUID используется 2 метода: `Validate` и `isInvalidOrEmpty`.
**Важно!** Лобой из вышеуказанных методов может выбросить исключение `JsonException`, если ключ не содержит вложений,
хотя от него требуется обратное.
#### Метод `Validate`
#### Метод `Write`
Это статичный метод проверяет корректность GUID. Он имеет только **1 параметр** - объект GUID или его строковое представление для проверки `GUID|null|string $guid`.
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**:
- `string $key` (ключ);
- `mixed $value` (записываемое значение).
Этот метод ничего не возвращает.
Этот метод возвращает `bool`: результат проверки.
Синтаксис:
public function Write (string $key, mixed $value): void
public static function Validate (string|GUID|null $guid): bool
**Пример,**
// Имя файла
$fileName = __DIR__ . "/test.json";
// Создаём класс
$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);
// Валидация класса GUID
echo GUID::Validate(new GUID ('00000000-0000-0000-0000-000000000000')) ? 'GUID верен' : 'GUID ошибочен';
Содержимое файла `test.json` представлено далее:
// Разделитель
echo '<br>';
{
"test": {
"subtest": {
"AAA": "123",
"BBB": 1.23
}
},
"test1": {
"test": 123
},
"test2": {
"test": true
},
"test3": {
"test": {
"res": "[1,2,3]"
}
}
}
// Валидация строки
echo GUID::Validate('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1') ? 'GUID верен' : 'GUID ошибочен';
// Разделитель
echo '<br>';
#### Метод `WriteArray`
// Валидация ошибки
echo GUID::Validate('НЕ GUID') ? 'GUID верен' : 'GUID ошибочен';
Это метод, который записывает значение в ключ JSON. Он имеет **2 обязательных параметра**:
В результате, на экране появится:
- `string $key` (ключ);
- `array $array` (записываемое значение).
GUID верен
GUID верен
GUID ошибочен
Этот метод ничего не возвращает.
#### Метод `isInvalidOrEmpty`
Это статический метод, который проверяет объекты GUID на корректность и на «пустое» значение. Он имеет только **1 параметр** - объект GUID или `null` для проверки `?GUID $guid`.
Этот метод возвращает `bool`: результат проверки GUID.
Синтаксис:
public function WriteArray (string $key, array $array): void
#### Метод `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
public static function isInvalidOrEmpty (?GUID $guid): 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->IsKeyExists("test/subtest/AAA");
$check2 = $json->IsKeyExists("test/subtest/ССС");
// Валидация класса GUID
echo GUID::isInvalidOrEmpty(new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1')) ? 'GUID верен' : 'GUID ошибочен';
В результате, `$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();
// Заполним данными
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();
// Выводим
echo GUID::Empty();
В результате, `$key1` будет следующим массивом:
В результате, на экране появится:
[
"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` будет следующим массивом:
[
]
00000000-0000-0000-0000-000000000000

View File

@ -61,34 +61,6 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
$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.
*
@ -129,6 +101,24 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
return new self($guid);
}
// Подключаем трейт реализующий интерфейс ISerializable
use GUIDSerializeTrait;
// Подключаем трейт реализующий интерфейс IArrayable
use GUIDArrayableTrait;
// Подключаем трейт реализующий интерфейс IDuplicated
use GUIDDuplicatedTrait;
// Подключаем трейт реализующий интерфейс JsonSerializable
use GUIDJsonSerializableTrait;
// Подключаем трейт реализующий интерфейс IHashable
use GUIDHashableTrait;
// Подключаем трейт реализующий интерфейс IComparable
use GUIDComparableTrait;
/**
* Проверяет, является ли GUID пустым или недействительным.
*
@ -138,17 +128,17 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
*/
public static function isInvalidOrEmpty (?GUID $guid): bool
{
return !self::Validate($guid) || $guid === self::EMPTY;
return !self::Validate($guid) || $guid->IsEqualsTo(self::Empty());
}
/**
* Валидирует строку GUID.
*
* @param mixed $guid Объект GUID или строка для проверки.
* @param string|GUID|null $guid Объект GUID или его строковое представление для проверки.
*
* @return bool Результат проверки.
*/
public static function Validate (mixed $guid): bool
public static function Validate (string|GUID|null $guid): bool
{
// Проверка на пустое значение
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;
}
/**
* Возвращает пустой GUID.
*
* @return GUID Пустой GUID.
*/
public static function Empty (): GUID
{
return new GUID();
}
/**
* Создает экземпляр GUID из массива байтов.
*
@ -193,19 +193,26 @@ final class GUID implements IArrayable, IDuplicated, ISerializable, IComparable,
/**
* Создает экземпляр 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
!self::Validate($guidString)
// - если GUID недействителен, выбрасываем исключение
? throw new InvalidArgumentException('Предан неверный GUID / Wrong GUID.')
// - иначе, создаем экземпляр GUID из строки
: new GUID($guidString);
// Проверка на валидность GUID
if (self::Validate($guidString))
// - если GUID действителен, возвращаем экземпляр GUID
return new GUID($guidString);
// Если же GUID недействителен и запрещено выбрасывать исключение
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;
use goodboyalex\php_components_pack\types\GUID;
use InvalidArgumentException;
use OutOfRangeException;
use PHPUnit\Framework\TestCase;
class GUIDTest extends TestCase
@ -28,26 +30,57 @@ class GUIDTest extends TestCase
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 ()
{
$this->PrepareForTest();
$guid = new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1');
$this->assertEquals('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1', $guid->ToString());
}
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 ()
{
$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 ()
{
$this->PrepareForTest();
$guid = new GUID ('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1');
$str = "$guid";
$this->assertEquals('5c0e5f0e-d033-44b1-a0b6-d0e2e369bdd1', $str);
}
public function testToBytes ()
@ -80,11 +113,17 @@ class GUIDTest extends TestCase
public function testGenerate ()
{
$this->PrepareForTest();
$guid = GUID::Generate();
self::assertFalse(GUID::isInvalidOrEmpty($guid));
}
public function testFromBytes ()
{
$this->PrepareForTest();
// Создаю массив
$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());
}
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'));
}
}