20250222
[О] [ClassMapper::GetDefaults]: Улучшено определение типа. Теперь проверка integer не вызовет ошибку, что ожидается int. [О] [ClassMapper::MapClass]: Теперь идёт проверка свойства на доступность get и set. Свойства с только get и только set пропускаются.
This commit is contained in:
		| @@ -9,6 +9,7 @@ use Exception; | ||||
| use ReflectionClass; | ||||
| use ReflectionException; | ||||
| use stdClass; | ||||
| use Throwable; | ||||
| use UnitEnum; | ||||
|  | ||||
| /** | ||||
| @@ -53,24 +54,54 @@ final class ClassMapper | ||||
|         // Задаю массив свойств | ||||
|         $properties = []; | ||||
|  | ||||
|         // Получаю имя исходного класса | ||||
|         $className = get_class($from); | ||||
|  | ||||
|         // Получение всех свойств класса | ||||
|         try { | ||||
|             $reflection = new ReflectionClass($className); | ||||
|         } | ||||
|         catch (ReflectionException) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Получение всех свойств класса | ||||
|         $reflection = new ReflectionClass(get_class($from)); | ||||
|         $props = $reflection->getProperties(); | ||||
|  | ||||
|         var_dump($props); | ||||
|         // Создаю экземпляр класса | ||||
|         $instance = new $className(); | ||||
|  | ||||
|         // Для каждого свойства | ||||
|         foreach ($props as $prop) { | ||||
|             // - получаю имя свойства | ||||
|             $propName = $prop->getName(); | ||||
|             $value = $from->$propName; // Читаем значение свойства | ||||
|             // - получаю значение свойства | ||||
|             $value = $from->$propName; | ||||
|  | ||||
|             try { | ||||
|                 $getterMethod = 'get' . ucfirst($propName); | ||||
|                 $setterMethod = 'set' . ucfirst($propName); | ||||
|                 // - получаю тип свойства | ||||
|                 $typeOf = gettype($from->$propName); | ||||
|  | ||||
|                 // Проверяем существование геттера и сеттера методами класса | ||||
|                 if (!(method_exists($from, $getterMethod) && method_exists($from, $setterMethod))) | ||||
|                 // - получаю значение свойства по типу и по умолчанию | ||||
|                 $writeValue = self::GetDefaults($typeOf); | ||||
|  | ||||
|                 try { | ||||
|                     // - проверяем, можно ли записать и прочитать значение | ||||
|                     // -- пытаюсь установить значение | ||||
|                     $instance->$propName = $writeValue; | ||||
|                     // -- пытаюсь прочитать установленное значение | ||||
|                     $readValue = $instance->$propName; | ||||
|  | ||||
|                     // -- и проверяю, что значение совпадают | ||||
|                     /** @noinspection PhpConditionAlreadyCheckedInspection */ | ||||
|                     if ($readValue !== $writeValue) | ||||
|                         continue; | ||||
|                 } | ||||
|                 catch (Throwable) { | ||||
|                     // - в случае ошибки, понимаем, что свойство доступно или только для чтения, или | ||||
|                     // только для записи и оно нам не подходит. Поэтому пропускаем его. | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // - если свойство игнорируется | ||||
|                 if (in_array($propName, $options['ignored'])) | ||||
| @@ -85,14 +116,12 @@ final class ClassMapper | ||||
|                 // Если не было ошибки, значит свойство имеет и геттер, и сеттер | ||||
|                 $properties[$propName] = $value; | ||||
|             } | ||||
|             catch (Error $exception) { | ||||
|                 var_dump($exception->getMessage()); | ||||
|                 // Игнорируем исключения, так как нас интересуют только свойства с обоими методами | ||||
|             catch (Error) { | ||||
|                 // - в случае ошибки, понимаем, что свойство нам не подходит. Поэтому пропускаю его. | ||||
|                 continue; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         var_dump($properties); | ||||
|  | ||||
|         // Для каждого элемента массива | ||||
|         foreach ($properties as $name => $value) { | ||||
|             // - если свойство есть в объекте | ||||
| @@ -102,6 +131,26 @@ final class ClassMapper | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Возвращает значение по умолчанию для типа $typeName. | ||||
|      * | ||||
|      * @param string $typeName Тип | ||||
|      * | ||||
|      * @return mixed Значение по умолчанию | ||||
|      */ | ||||
|     public static function GetDefaults (string $typeName): mixed | ||||
|     { | ||||
|         return match (strtolower($typeName)) { | ||||
|             'int', 'integer' => 0, | ||||
|             'float', 'double' => 0.0, | ||||
|             'bool', 'boolean' => false, | ||||
|             'string' => '', | ||||
|             'array' => [], | ||||
|             'object' => new stdClass(), | ||||
|             default => null, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Подготавливает значения свойств класса. | ||||
|      * | ||||
| @@ -347,25 +396,4 @@ final class ClassMapper | ||||
|             throw new Exception($exception->getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Получает значение по умолчанию для разных типов данных. | ||||
|      * | ||||
|      * @param string $typeName Имя типа данных. | ||||
|      * | ||||
|      * @return mixed|null Результат. | ||||
|      */ | ||||
|     public | ||||
|     static function GetDefaults (string $typeName): mixed | ||||
|     { | ||||
|         return match ($typeName) { | ||||
|             'int' => 0, | ||||
|             'float' => 0.0, | ||||
|             'bool' => false, | ||||
|             'string' => '', | ||||
|             'array' => [], | ||||
|             'object' => new stdClass(), | ||||
|             default => null, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user