20250214
+ [TwoDimSize]: Класс, описывающий двумерный размер. + [HashGetType]: Перечисление типов получения хэша. + [FileHash]: Класс для работы с хэшем файла или строки.
This commit is contained in:
		
							
								
								
									
										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); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user