runz0rd / mapper-php
模型映射、取消映射和验证
Requires
- runz0rd/common-php: 2.2.*
Requires (Dev)
- phpunit/phpunit: ~5
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)
- 提供验证定义,如果它未通过则抛出异常(validate)
- 规则参数(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)来使用自定义规则。
代码示例
请参阅其中使用的测试和模型。