dataclass позволяет вам быстро изменить ваш простой array
на класс PHP с подсказками по типу с автоматической денормализацией встроенных объектов и коллекций, что обычно требует большой работы, если вы используете нормализаторы и денормализаторы. Библиотека основана на модуле Python pydantic. Он использует возможности подсказки типов, доступные начиная с PHP 7.4.
Основная цель этого пакета — предоставить быстрый способ создания классов со строгой типизацией для дальнейшего использования, например, для сопоставления полезных данных запроса со строго типизированным классом, чтобы вы могли использовать его вместо массива, который может соответствовать или не соответствовать вашим требованиям. Это не заменит проверку данных, но позволит вам убедиться, что полученная fx полезная нагрузка JSON соответствует типам, которые ожидают получить ваши серверные операции. Это что-то вроде упомянутого выше интерфейса pydantic BaseModel
или TypeScript.
Все, что вам нужно, это создать класс или два:
declare (strict_types= 1 );
class MyEmbededClass
{
public float $ number ;
}
class MyClass
{
public int $ number ;
public ? string $ optionalText = null ;
public MyEmbededClass $ embeded ;
}
На следующем шаге передайте имя основного класса и полученные данные, например, из полученного JSON, в метод transform
:
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ object = transform (MyClass::class, json_decode ( $ data , true ));
Чтобы быстро сопоставить полученные данные с полнофункциональным dataclass :
var_dump ( $ object )
object (MyClass) {
[ " number " ]=> int( 1 )
[ " optionalText " ]=> NULL
[ " embeded " ]=>
object(MyEmbededClass) {
[ " number " ]=>
float( 1.23 )
}
}
Вам не нужно беспокоиться о передаче значения null
из json_decode
, оно выдаст TransformException
для root
поля, если оно будет обнаружено.
Вам не нужно беспокоиться об отсутствующих полях и недопустимых типах, поскольку библиотека обнаруживает все требования с подсказками по типу и выдает TransformException
с ошибками (готовыми к использованию в качестве ответа), указывающими на точные поля с простым сообщением причины, например:
echo json_encode ( $ transformException , JSON_PRETTY_PRINT )
{
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
}
Вы также можете использовать метод Transform::to
, который на самом деле вызывается вспомогательной функцией transform
. Вспомогательная функция всегда будет использовать оптимальные настройки для объектов Transform
(как только они появятся).
$ data = ' {
"number": 1,
"embeded": {
"number": 1.23
}
} ' ;
$ transformer = new Transform ();
$ object = $ transformer -> to (MyClass::class, json_decode ( $ data , true ));
Если вам нужно использовать конструктор с аргументами с указанием типа, вы можете это сделать, но ограниченным способом. Библиотека поддерживает только заполнение аргументов конструктора значениями из полезных данных. Это означает, что конструктор должен использовать те же типы и имена переменных, что и свойства класса. Например:
class MyClass
{
public float $ number ;
public ? int $ numberTwo = null ;
public function __construct ( float $ number )
{
$ this -> number = $ number ;
}
}
Использование другого имени или типа для аргумента конструктора не сработает. Цель состоит в том, чтобы заставить разработчика заполнять свойства.
Любой конструктор, который содержит любой другой параметр, кроме свойств, выдаст UnsupportedException
. Параметры должны иметь тот же тип, что и свойства. Порядок не имеет значения. Если это необходимо, в конструкторе может существовать только некоторое подмножество свойств.
Пожалуйста, посетите каталог docs/ для получения дополнительных примеров.
Так просто, как
composer install rutek/ dataclass
Внимание: помните об использовании подсказок по типу array
. Их нельзя использовать (при обнаружении выдается исключение UnsupportedException
), поскольку PHP не предоставляет возможности подсказки по типу элементов массива. Пожалуйста, проверьте раздел «Коллекции» ниже для получения дополнительной информации.
Поддерживаются все четыре скаляра PHP.
Поддерживается обнуляемость подсказок типов. Вы можете безопасно использовать, например ?string
для принятия как string
так и null
. Имейте в виду, что использование только ?string $field
не означает, что преобразованный массив не может содержать это поле. Это означает только то, что это значение принимает null
.
Если вам нужно принять преобразование данных, которые не содержат некоторых полей, вы можете использовать значения по умолчанию, например: ?string $field = null
. Библиотека dataclass обнаружит, что это свойство не существует в полезных данных, и вместо этого будет использовать значение по умолчанию.
PHP не поддерживает поля array
с подсказками типов, если вам нужно внедрить коллекцию объектов или скаляров, вам придется использовать класс Collection
. Вам необходимо расширить его с помощью конструктора с деконструкцией аргументов с указанием типа, например:
class Tags extends Collection
{
public function __construct ( string ... $ names )
{
$ this -> items = $ names ;
}
}
Массивы с подсказками типа, такие как string[]
были отклонены в RFC, поэтому, возможно, это поведение не изменится в ближайшее время.
Библиотека проверит, соответствуют ли предоставленные значения указанию типа конструктора.
Нет возможности проверять минимальное и максимальное количество элементов, но такая функция может появиться в следующих версиях.
Обратите внимание, что вы также можете использовать Collection в качестве базового класса, который хотите преобразовать, например:
$ tags = transform (Tags::class, [ ' tag1 ' , ' tag2 ' ]);
TransformException
— данные не соответствуют вашей схеме Это базовое исключение, которого вы можете ожидать. Каждый раз, когда ваши данные (полезная нагрузка), передаваемые в функцию transform(string $class, $data)
или Transform::to
не будут соответствовать вашим классам с подсказками по типу, вы получите TransformException
с методом getErrors(): FieldError[]
который описывает то, что на самом деле случилось.
Каждый FieldError
содержит как field
описывающее, какое поле не прошло проверку типа, так и reason
описывающую простыми словами, почему оно было отклонено. Если есть вложенные объекты, вы можете рассчитывать на получение значений field
, таких как parentProperty.childrenProperty
(уровни, разделенные точкой).
Класс поддерживает сериализацию JSON и всегда будет возвращать что-то вроде:
{
"errors" : [
{
"field" : " optionalText " ,
"reason" : " Field must have value "
},
{
"field" : " embeded " ,
"reason" : " Field must have value "
}
]
}
Обратите внимание, что поле code
может быть добавлено в будущем.
UnsupportedException
— только если ваши подсказки типов не поддерживаются. Библиотека не охватывает все сценарии, поскольку вы можете определять подсказки типов, которые не будут иметь строгого контекста. Например, если вы используете свойство object
, его невозможно проверить, поскольку любой объект будет соответствовать вашей схеме. В таких случаях вы можете ожидать UnsupportedException
.
Типы объединения PHP 8.0 и типы пересечения PHP 8.1 в настоящее время не поддерживаются.
Собственные перечисления PHP 8.1 сейчас не поддерживаются.
На данный момент все поля с подсказками по типу должны быть общедоступными. Реализация такой функции сомнительна, поскольку вам придется создавать методы получения для таких свойств, что является нежелательными накладными расходами. Библиотека предназначена для создания возможности определять внутренние схемы для данных, полученных от удаленных систем (API, очереди/сообщения шины, браузеры).
Все проверки отражения выполняются каждый раз при вызове функции transform
или Transform::to
. В ближайшее время вы можете ожидать функциональности кэширования для повышения производительности.
Помните, что целью этого пакета является не полная проверка получаемых вами данных, а создание простых классов, которые делают ваши полезные нагрузки полностью типизированными, даже если они имеют сложную структуру. Вам не придется кодировать классы в формате JSON с полями class
, поскольку подсказки типов сообщат вашему коду, какой объект или массив следует создать вместо некоторых встроенных значений.
Если вы создаете API и вам нужна проверка схемы OpenAPI корпоративного уровня, вам следует проверить hkarlstrom/openapi-validation-middleware, а затем вы можете сопоставить полученную полезную нагрузку с классами с подсказками по типу, используя эту библиотеку! :)