ttbooking / mapper-php
模型映射、取消映射和验证
Requires
- php: ^8.0
- ttbooking/common-php: ^2.3
Requires (Dev)
- phpunit/phpunit: ~9
Suggests
- ext-dom: DOM extension
- ext-libxml: LibXML extension
README
功能列表
- 从json、xml、数组和其他对象映射PHP类属性。
- 从模型到json、xml、数组和stdClass取消映射
- 支持嵌套模型
- 注解提供模型属性的自定义命名、类型和规则
- 正确注解并映射的模型可以验证不同类型和规则
安装
composer require runz0rd/mapper-php
工作原理
映射器会遍历您模型的所有属性名称(您可以使用 @name 更改属性名称映射),如果有的话,映射与源(json/xml/array/stdClass)中相同名称的属性。映射后的模型可以直接使用,但建议在映射后对其进行验证。必需的属性(@required)必须始终设置并具有适当的类型(如果使用 @var 或 @rule 设置)。非必需属性可以不设置(null),但如果设置,则必须与定义的类型或规则(如果使用 @var 或 @rule 设置)匹配以通过验证。所以,如果您有
{ "name": "Jack", "type": "human", "age": 35, "isEmployed": true, "custom-desc": "lazy" }
您可以这样创建一个模型
class SomeGuy { /** * @required * @var string */ public $name; /** * @required createSomeGuy * @var string */ public $type; /** * @rule limit(1,150) * @var integer */ public $age; /** * @var boolean */ public $isEmployed; /** * @name custom-desc * @var string */ public $description }
如果以下条件成立,验证将失败
- 您使用 createSomeGuy 操作,但没有(null) $type(仅在 createSomeGuy 操作中必需)
- 没有(null) $name(始终必需)
- 您使用 createSomething 操作,并且 $type 不是一个字符串
- $name 不是一个字符串
- $age 被设置(非 null),但不是一个整数,或不在1到150之间(规则)
- $isEmployed 被设置(非 null)但不是一个布尔值
请注意,$description 将会被映射,因为它设置了 @name 注解,并且源中有匹配该名称的属性(custom-desc)。
注解
以下是我们在模型中可以使用的注解列表
@var 注解类型列表
用法
映射
在您的模型中使用 MappableTrait 来调用模型本身的方法
$model->mapFromArray($myArray); $model->mapFromJson($myJson); $model->mapFromXml($myXml); $model->mapFromObject($myObject);
或者通过使用 ModelMapper 类,提供您想要映射的模型的实例和源对象
$model = new Model(); $mapper = new ModelMapper(); $mapper->map($sourceObject, $model);
取消映射
在您的模型中使用 ConvertibleTrait 来调用模型本身的方法
$myArray = $model->toArray(); $myJson = $model->toJson(); $myXml = $model->toXml(); $myObject = $model->toObject();
或者通过使用 ModelMapper 类,提供映射后的模型(转换为 stdClass)
$mapper = new ModelMapper(); $myObject = $mapper->unmap($myModel);
验证
验证将检查您映射后的模型属性的类型、自定义规则以及属性是否必需。
使用 ValidatableTrait 验证您的映射模型,通过提供所需的验证操作
$model->validate('createAction');
或者如果您只想验证始终必需的属性
$model->validate();
您也可以直接使用验证器本身
$model = new Model(); $validator = new ModelValidator(); $validator->validate($model, 'myAction');
规则
规则用于对映射属性值进行自定义验证。
/** * @rule email */ public $email;
这将检查属性值是否包含有效的电子邮件字符串。
您可以为规则传递额外的参数。
/** * @rule limit(0,99) */ public $value;
如果设置正确,此自定义规则将检查属性值是否在0到99之间。
规则设置
让我们使用上面的 limit 规则示例来创建一个新的自定义规则
use Common\ModelReflection\ModelProperty; use Validator\IRule; use Validator\ModelValidatorException; class LimitRule implements IRule { function getNames() { return ['limit']; } function validate(ModelProperty $property, array $params = []) { if($property->getPropertyValue() < $params[0] || $property->getPropertyValue() > $params[1]) { throw new ModelValidatorException('Value is not between '.$params[0].' and '.$params[1]); } } }
在上面的示例中,我们可以通过以下方式配置一个新规则
- 定义一个名称(别名)数组,这些名称作为注解中的规则名称(getNames)
- 提供验证定义,并在不通过时抛出异常(验证)
- 规则参数(0,99)通过 $params 数组传入,按提供顺序排列
有关更多信息,请查看预定义的规则类和 IRule 接口。
加载您的规则
$model = new Model(); $myCustomRule = new MyCustomRule(); $validator = new ModelValidator(); $validator->useRule($myCustomRule); $validator->loadRules('/path/to/rules/'); $validator->validate($model, 'myAction');
在上面的示例中,我们可以通过逐个提供给验证器自定义规则(useRule)或提供包含规则的目录路径(loadRules)来使用自定义规则。
代码示例
请查看其中使用的测试和模型。