20250214
+ [TwoDimSize]: Класс, описывающий двумерный размер. + [HashGetType]: Перечисление типов получения хэша. + [FileHash]: Класс для работы с хэшем файла или строки.
This commit is contained in:
parent
3fd75364a1
commit
b6f9698e59
79
sources/classes/FileHash.php
Normal file
79
sources/classes/FileHash.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_components_pack\classes;
|
||||
|
||||
use goodboyalex\php_components_pack\enums\HashGetType;
|
||||
use goodboyalex\php_components_pack\extensions\StringExtension;
|
||||
|
||||
/**
|
||||
* Класс для работы с хэшем файла или строки.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0.5
|
||||
*/
|
||||
final class FileHash
|
||||
{
|
||||
/**
|
||||
* @var string $Hash Хэш файла.
|
||||
*/
|
||||
private(set) string $Hash;
|
||||
|
||||
/**
|
||||
* @var HashGetType Тип получения хэша.
|
||||
*/
|
||||
public HashGetType $HashBy;
|
||||
|
||||
/**
|
||||
* Конструктор.
|
||||
*
|
||||
* @param string $str Строка или имя файла.
|
||||
* @param HashGetType $HashBy Тип получения хэша.
|
||||
*/
|
||||
public function __construct (string $str = "", HashGetType $HashBy = HashGetType::ByString)
|
||||
{
|
||||
$this->HashBy = $HashBy;
|
||||
$this->Hash = match ($HashBy) {
|
||||
HashGetType::ByString => $this->pGetHash($str),
|
||||
HashGetType::ByFile => $this->pGetFileHash($str)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение хэша файла по строке.
|
||||
*
|
||||
* @param string $str Строка.
|
||||
*
|
||||
* @return string Хэш строки.
|
||||
*/
|
||||
private function pGetHash (string $str): string
|
||||
{
|
||||
return hash('sha256', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение хэша файла по имени файла.
|
||||
*
|
||||
* @param string $fileName Имя файла.
|
||||
*
|
||||
* @return string Хэш файла.
|
||||
*/
|
||||
private function pGetFileHash (string $fileName): string
|
||||
{
|
||||
return hash_file('sha256', $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Сравнивает текущий хэш с хэшем <code>otherHash</code> и выдаёт <code>true</code>, если совпадают, и
|
||||
* <code>false</code>, если не совпадают.
|
||||
*
|
||||
* @param FileHash $otherHash Другой хэш.
|
||||
*
|
||||
* @return bool <code>true</code>, если совпадают, и <code>false</code>, если не совпадают.
|
||||
*/
|
||||
public function IsEqual (FileHash $otherHash): bool
|
||||
{
|
||||
return StringExtension::Compare($this->Hash, $otherHash->Hash, true) === 0;
|
||||
}
|
||||
}
|
183
sources/classes/TwoDimSize.php
Normal file
183
sources/classes/TwoDimSize.php
Normal file
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_components_pack\classes;
|
||||
|
||||
use Exception;
|
||||
use goodboyalex\php_components_pack\interfaces\ISerializable;
|
||||
|
||||
/**
|
||||
* Класс, описывающий двумерный размер.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0.5
|
||||
*/
|
||||
final class TwoDimSize implements ISerializable
|
||||
{
|
||||
/**
|
||||
* Разделитель частей по умолчанию.
|
||||
*/
|
||||
public const string DEFAULT_DELIMITER = ':';
|
||||
|
||||
/**
|
||||
* @var bool $NoNegativeValues Значения не должны быть отрицательными.
|
||||
*/
|
||||
public bool $NoNegativeValues = true;
|
||||
|
||||
/**
|
||||
* @var int $Width Длина (публичная)
|
||||
*/
|
||||
public int $Width {
|
||||
get {
|
||||
return $this->pWidth;
|
||||
}
|
||||
set {
|
||||
$this->pWidth = $this->NoNegativeValues ? max($value, 0) : $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int $Height Ширина (публичная)
|
||||
*/
|
||||
public int $Height {
|
||||
get {
|
||||
return $this->pHeight;
|
||||
}
|
||||
set {
|
||||
$this->pHeight = $this->NoNegativeValues ? max($value, 0) : $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int $pWidth Длина (приватное)
|
||||
*/
|
||||
private int $pWidth = 0;
|
||||
|
||||
/**
|
||||
* @var int $pHeight Ширина (приватное)
|
||||
*/
|
||||
private int $pHeight = 0;
|
||||
|
||||
/**
|
||||
* Конструктор.
|
||||
*
|
||||
* @param int $width Длина.
|
||||
* @param int $height Ширина.
|
||||
* @param bool $noNegativeValues Значения не должны быть отрицательными.
|
||||
*/
|
||||
public function __construct (int $width = 0, int $height = 0, bool $noNegativeValues = true)
|
||||
{
|
||||
$this->Width = $width;
|
||||
$this->Height = $height;
|
||||
$this->NoNegativeValues = $noNegativeValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертация в строку (магический метод).
|
||||
*
|
||||
* @return string Строка.
|
||||
*/
|
||||
public function __toString (): string
|
||||
{
|
||||
return $this->AsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертация в строку (расширенный метод).
|
||||
*
|
||||
* @param string $delimiter Делитель размера.
|
||||
*
|
||||
* @return string Строка.
|
||||
*/
|
||||
public function AsString (string $delimiter = self::DEFAULT_DELIMITER): string
|
||||
{
|
||||
return $this->Width . $delimiter . $this->Height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function Serialize (): string
|
||||
{
|
||||
// Получаю строковое значение
|
||||
$str = $this->AsString("x");
|
||||
|
||||
// Добавляю допустимы ли отрицательные значения
|
||||
$str .= $this->NoNegativeValues ? "x1" : "x0";
|
||||
|
||||
// Возвращаю строку
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function UnSerialize (string $serialized): void
|
||||
{
|
||||
// Десериализую строку
|
||||
$result = explode("x", $serialized);
|
||||
|
||||
// Присваиваю параметры
|
||||
$this->NoNegativeValues = $result[2] === "1";
|
||||
|
||||
// Объединяю длину и ширину
|
||||
$tdSize = $result[0] . self::DEFAULT_DELIMITER . $result[1];
|
||||
|
||||
// Пытаюсь получить размер
|
||||
try {
|
||||
$result = self::Parse($tdSize, noNegativeValues: $this->NoNegativeValues);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$result = new TwoDimSize(noNegativeValues: $this->NoNegativeValues);
|
||||
}
|
||||
|
||||
// Присваиваю длину
|
||||
$this->Width = $result->Width;
|
||||
|
||||
// Присваиваю ширину
|
||||
$this->Height = $result->Height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение размера из строки.
|
||||
*
|
||||
* @param string $str Строка.
|
||||
* @param string $delimiter Разделитель размеров.
|
||||
* @param bool $noNegativeValues Значения не должны быть отрицательными.
|
||||
*
|
||||
* @return TwoDimSize Модель размеров.
|
||||
* @throws Exception Если в строке <code>str</code> не содержится символа <code>delimiter</code> или таких
|
||||
* разделителей слишком много.
|
||||
*/
|
||||
public static function Parse (string $str, string $delimiter = self::DEFAULT_DELIMITER,
|
||||
bool $noNegativeValues = true): TwoDimSize
|
||||
{
|
||||
// Разделяю значения
|
||||
$splitSizes = explode($delimiter, $str);
|
||||
|
||||
// Проверяю, что массив имеет ровно два элемента
|
||||
if (count($splitSizes) != 2)
|
||||
throw new Exception(sprintf("Похоже, что в строке %s не содержится символа «%s» или таких разделителей слишком много!",
|
||||
$str, $delimiter));
|
||||
|
||||
// Пытаюсь получить длину
|
||||
$width = filter_var($splitSizes[0], FILTER_VALIDATE_INT);
|
||||
|
||||
// Если не удалось получить длину
|
||||
if ($width === false)
|
||||
$width = 0;
|
||||
|
||||
// Пытаюсь получить ширину
|
||||
$height = filter_var($splitSizes[1], FILTER_VALIDATE_INT);
|
||||
|
||||
// Если не удалось получить ширину
|
||||
if ($height === false)
|
||||
$height = 0;
|
||||
|
||||
// Вывожу значение
|
||||
return new TwoDimSize($width, $height, $noNegativeValues);
|
||||
}
|
||||
}
|
29
sources/enums/HashGetType.php
Normal file
29
sources/enums/HashGetType.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_components_pack\enums;
|
||||
|
||||
use goodboyalex\php_components_pack\traits\EnumExtensionsTrait;
|
||||
|
||||
/**
|
||||
* Перечисление типов получения хэша.
|
||||
*
|
||||
* @author Александр Бабаев
|
||||
* @package php_components_pack
|
||||
* @version 1.0
|
||||
* @since 1.0.5
|
||||
*/
|
||||
enum HashGetType: int
|
||||
{
|
||||
// Подключаю расширение для Enum
|
||||
use EnumExtensionsTrait;
|
||||
|
||||
/**
|
||||
* По строке.
|
||||
*/
|
||||
case ByString = 0;
|
||||
|
||||
/**
|
||||
* По файлу.
|
||||
*/
|
||||
case ByFile = 1;
|
||||
}
|
42
tests/classes/FileHashTest.php
Normal file
42
tests/classes/FileHashTest.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_components_pack\tests\classes;
|
||||
|
||||
use goodboyalex\php_components_pack\classes\FileHash;
|
||||
use goodboyalex\php_components_pack\enums\HashGetType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FileHashTest extends TestCase
|
||||
{
|
||||
public function test__construct ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
$fileHash = new FileHash("Тестовое слово");
|
||||
$this->assertEquals("000e22f7ba01ae35f781bc3069038110c46593306cafef6b489f7c83b34629b7", $fileHash->Hash);
|
||||
|
||||
$fileHash = new FileHash(__DIR__ . '/../data/A.php', HashGetType::ByFile);
|
||||
$this->assertEquals("fc8dad93af5de5dd7c7d64e04faadfa22557e577a1538737fe462a5f78699fa2", $fileHash->Hash);
|
||||
|
||||
$fileHash = new FileHash(__DIR__ . '/../data/B.php', HashGetType::ByFile);
|
||||
$this->assertEquals("f419262e46e9461517af46d0c1e4faf25f38990bb50351b691d84f1ad51f2299", $fileHash->Hash);
|
||||
}
|
||||
|
||||
private function PrepareForTest (): void
|
||||
{
|
||||
require_once __DIR__ . '/../../sources/traits/EnumExtensionsTrait.php';
|
||||
require_once __DIR__ . '/../../sources/enums/HashGetType.php';
|
||||
require_once __DIR__ . '/../../sources/extensions/StringExtension.php';
|
||||
require_once __DIR__ . '/../../sources/classes/FileHash.php';
|
||||
}
|
||||
|
||||
public function testIsEqual ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
$fileHash = new FileHash("Тестовое слово");
|
||||
|
||||
$this->assertTrue($fileHash->IsEqual(new FileHash("Тестовое слово")));
|
||||
$this->assertFalse($fileHash->IsEqual(new FileHash("Тестовое слово2")));
|
||||
}
|
||||
}
|
66
tests/classes/TwoDimSizeTest.php
Normal file
66
tests/classes/TwoDimSizeTest.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace goodboyalex\php_components_pack\tests\classes;
|
||||
|
||||
use Exception;
|
||||
use goodboyalex\php_components_pack\classes\TwoDimSize;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TwoDimSizeTest extends TestCase
|
||||
{
|
||||
public function testParse ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
try {
|
||||
$size = TwoDimSize::Parse("10x20", "x");
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$this->fail($e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertEquals(10, $size->Width);
|
||||
$this->assertEquals(20, $size->Height);
|
||||
|
||||
}
|
||||
|
||||
private function PrepareForTest (): void
|
||||
{
|
||||
require_once __DIR__ . '/../../sources/interfaces/ISerializable.php';
|
||||
require_once __DIR__ . '/../../sources/classes/TwoDimSize.php';
|
||||
}
|
||||
|
||||
public function test__toString ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
$size = new TwoDimSize(10, 20);
|
||||
|
||||
$this->assertEquals("10:20", $size->__toString());
|
||||
}
|
||||
|
||||
public function testSerialize ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
$size = new TwoDimSize(10, 20);
|
||||
|
||||
$this->assertEquals("10x20x1", $size->Serialize());
|
||||
|
||||
}
|
||||
|
||||
public function testUnSerialize ()
|
||||
{
|
||||
$this->PrepareForTest();
|
||||
|
||||
$serialized = "10x20x1";
|
||||
|
||||
$size = new TwoDimSize();
|
||||
|
||||
$size->UnSerialize($serialized);
|
||||
|
||||
$this->assertEquals(10, $size->Width);
|
||||
$this->assertEquals(20, $size->Height);
|
||||
$this->assertTrue($size->NoNegativeValues);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user