piggly / php-value-types
不可变值对象,便于格式化和断言值。
Requires
- php: ^7.2 || ^8.0
- bjeavons/zxcvbn-php: ^1.2
- respect/validation: ^2.2
Requires (Dev)
- php: ^7.3 || ^8.0
- fakerphp/faker: ^1.14
- phpunit/phpunit: ^9.5
README
这个库主要是为了API系统开发的。但是,它也可以应用于任何系统。
什么是值对象?
值对象是一个小型对象,它代表一个简单的实体,其等价性不是基于身份:即当两个值对象具有相同的值时,它们是相等的,不一定是指同一个对象。值对象的例子包括表示金额或日期范围的对象。有关更多信息,请参阅这里。
安装
Composer
- 在您的控制台,在您的项目文件夹中,输入
composer require piggly/php-value-types
; - 别忘了在您的代码库中添加Composer的autoload文件
require_once('vendor/autoload.php');
。
手动安装
- 使用
git clone https://github.com/piggly-dev/php-value-types.git
下载或克隆存储库; - 然后,进入
cd /path/to/piggly/php-value-types
; - 使用
composer install
安装所有Composer依赖项; - 在您的代码库中添加项目的autoload文件
require_once('/path/to/piggly/php-value-types/vendor/autoload.php');
。
依赖项
该库有以下外部依赖
- PHP 7.2+。
它能帮什么忙?
想象一个处理电子邮件的应用程序。即使电子邮件的值不同,它们的行为也是相同的。它们具有一种模式,并且必须始终是电子邮件。在您的应用程序服务中,有许多具有电子邮件的实体,例如:用户、订单、公司等。
没有值对象,您可能需要在任何具有电子邮件的实体中检查电子邮件模式。但是,有了值对象,您可以设置这种行为,而不是使用基本类型作为字符串,您将使用 EmailType
对象。
在任何应用程序点,它都会知道所有的 EmailType
处理电子邮件,并且始终返回一个有效的电子邮件。您的业务逻辑不需要关心如何处理电子邮件,因为您的 EmailType
对象会处理。
这个库是如何工作的?
在API环境中,我们可以处理很多数据。但不仅仅是纯数据,有时我们必须检查数据是否在需要时填充,或者数据是否符合限制、长度等要求。
这个库将不同的值类型标准化为对象。任何值对象都可以有一个或多个断言来验证是否为预期的数据。这使得验证过程既快又一致,您的API不需要关心如何处理数据,因为值对象会处理。
任何值对象都必须扩展 AbstractValueType
,它包含一个不可变的 $value
,一旦设置,将永远不会更改,并且必须是预期的值类型。
AbstractValueType
负责对象断言,设置默认值或使用 __toString()
方法将任何子类转换为 string
。
断言是如何工作的?
断言通过以下三种方法运行
validate()
,始终返回一个boolean
,指示当所有断言都通过时返回true
,或者如果任何断言失败则返回false
;caught()
,与validate()
方法的运行行为相同,但不是在任意断言失败时返回false
,而是返回一个包含断言产生的信息的string
。assert()
,如果任意断言失败,将始终抛出InvalidValueTypeOfException
异常。
您可以通过使用apply( $rule )
方法向一个值类型对象添加断言。该$rule
方法必须是一个实现了Piggly\ValueTypes\Interfaces\Validatable
或Respect\Validation\Validatable
接口的对象。
默认情况下,对象可以在constructor
方法中实现断言。
必需行为
为任何AbstractValueType
实现的唯一断言是必需行为。当构建一个值类型对象时,您可以设置$required
参数为true
。如果发生这种情况,则AbstractValueType
将评估$value
是否为null
并且必需在所有断言之前或当$value
为null
但不必需时抛出InvalidValueTypeOfException
,或断言值停止其他断言。
断言缓存
由于值对象是不可变的,断言必须只运行一次。因此,在第一次运行后它们将被缓存,即使您调用任何断言方法,它也将始终返回相同的结果。
但是,存在一个例外。如果您对值对象应用新的断言,它将丢失缓存并再次只运行一次。
常见对象
基本上,常见对象负责解析。它们将始终解析在constructor
中设置的任何$value
到期望的数据类型。有六个常见对象,它们扩展并替换了原始数据类型。请参阅
ArrayType
处理任何$value
,将其解析为有效的array
原始类型。它可以处理甚至包含以下方法的JSON
字符串和对象:toArray()
、toJson()
和jsonSerialize()
;BooleanType
处理任何$value
,将其解析为有效的boolean
原始类型;FloatType
和IntegerType
分别处理任何$value
,将其解析为有效的float
和integer
原始类型;JsonType
处理任何包含解析为有效的JSON
的$value
,将其解析为有效的string
原始类型。它可以处理包含以下方法的JSON
字符串和对象:toArray()
、toJson()
和jsonSerialize()
;StringObject
处理任何$value
,将其解析为有效的string
原始类型。它将任何内容转换为string
,即使是实现了或没有实现__toString()
方法的对象。
ArrayType
和JsonType
是唯一在无法将value
解析为期望的类型时在constructor
中抛出InvalidValueTypeOfException
的值类型。
高级对象
它们是自我解释的,与Common Objects
不同,它们处理更具体的行为和模式。请参阅
CnhType
,期望巴西驾照;CnpjType
,期望巴西企业注册号(CNPJ)号码;CountryCodeType
,期望ISO 3166-1标准的国家代码;CpfType
,期望巴西CPF号码;CreditCardType
,期望信用卡号码;CurrencyCodeType
,期望ISO 4217货币代码,如GBP或EUR;DateTimeType
,期望任何日期时间值;DateType
,期望任何日期值;DigitsType
,期望只包含数字的string
;EmailType
,期望电子邮件地址;HexRgbColorType
,期望十六进制到RGB颜色;IpType
,期望IP地址;PasswordType
,期望密码。它具有增强的行为,请参阅以下内容;PhoneType
,期望电话号码。PostalCodeType
,期望一个邮编;SlugType
,处理任何string
值到一个缩写名;UnixTimestampType
,期望一个整数作为 UNIX 时间戳;UrlType
,期望一个 URL;UuidType
,期望一个 UUID;Uuidv1Type
,期望一个 UUIDv1;Uuidv3Type
,期望一个 UUIDv3;Uuidv4Type
,期望一个 UUIDv4;Uuidv5Type
,期望一个 UUIDv5;VersionType
,期望使用语义版本控制的一个版本;
掩码行为
一些 高级对象 具有掩码其数据的特性:例如,example@gmail.com
可以被掩码为 e******@g****.com
或 e*@g*.com
。掩码对象扩展了 AbstractMaskedType
并有两个方法
isMasked() : bool
,返回值是否被掩码;masked( bool $keepLength = true ) : bool
,返回掩码值而不修改原始值。当keepLength
为true
时将保持值长度如e******@g****.com
,当为false
时将“压缩”为e*@g*.com
。
掩码一个值永远不会修改值对象。这意味着如果您有 new EmailType('example@gmail.com.br')
并且想要持久化掩码值或者只提供掩码值,您必须:new EmailType( $emailType->masked() );
。
密码增强行为
加密
PasswordType
对象具有增强的行为。
当构造它时,构造函数将评估密码是否使用 password_hash()
本地函数加密。如果没有,它将根据 PasswordType::hash()
静态方法设置的选项进行加密。默认情况下,加密将使用 \PASSWORD_BCRYPT
算法并使用默认选项。
在哈希之后,您将永远无法再次获得原始密码。但是,您可以使用 check( $raw )
方法始终验证哈希。
强度
另一方面,仍然在 constructor
中,它将使用 PasswordStrengthLib
对象评估密码强度,如果密码不符合所需的最低强度,则抛出 InvalidValueTypeOfException
。
PasswordStrengthLib
是一个实现
strength ( $raw )
,返回一个介于 0 和 100 之间的整数,表示密码强度。如果密码不符合要求,返回false
;getMessage ()
,可能返回一个说明密码强度失败原因的string
。
默认情况下,此库中有三个 libs
可用
PasswordBasicLib
,它实现了zxcvbn
算法;PasswordCrackLib
,它使用cracklib-checker
命令;PasswordPwScoreLib
,它使用pwscore
命令。
PasswordBasicLib
默认应用于 PasswordType
对象。实现所有可用的库可以增加密码强度检查的准确性。
自定义对象
您可以在任何时候创建自定义对象,这些对象始终扩展 AbstractValueType
并准备自己的断言。
示例
您可以在 /samples 文件夹中看到非常轻量级的示例。
变更日志
请参阅 CHANGELOG 文件以了解所有代码更改的信息。
测试代码
此库使用 PHPUnit。我们对该应用程序的所有主要类进行测试。
vendor/bin/phpunit
您必须始终使用 PHP 7.2 或更高版本运行测试。
贡献
在提交您的贡献之前,请参阅 CONTRIBUTING 文件以获取信息。
致谢
支持项目
Piggly Studio 是一家位于巴西里约热内卢的代理机构。如果您喜欢这个库并且想支持这项工作,请随意向 BTC 钱包 3DNssbspq7dURaVQH6yBoYwW3PhsNs8dnK
捐赠任何金额 ❤。
许可
MIT许可证(MIT)。查看许可证。