icecave / parity
一个可定制的深度比较库。
3.0.1
2021-02-04 05:51 UTC
Requires
- php: >=7.3
- icecave/repr: ^4
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-04 13:33:00 UTC
README
Parity 是一个用于 PHP 的深度比较库。
composer require icecave/parity
原因
PHP 无法提供一种可靠且严格地比较不同类型值的方法。大多数内置比较运算符经常会进行不希望的 类型转换。一个例外是 严格相等运算符,它有一个进一步的缺点,即它只能通过它们的身份来比较对象。没有提供类型严格机制来比较对象的属性;也没有提供相对比较运算符(小于、大于等)的类型严格版本。
Parity 通过提供以下功能的比较引擎来填补这一空白
- 通过元素类型严格比较数组和对象
- 递归安全的对象比较
- 内置类型自然、类型严格的比较语义
- 强大的机制,使类能够自定义比较行为
示例
可以通过 Parity
门面类的静态方法访问 Parity 比较引擎。这些方法接受任何类型,并保证产生一个确定性的比较结果1。以下是一些使用整数的简单示例。
use Icecave\Parity\Parity; // The compare() method provides a strcmp-style comparison, and hence can be // used as a sorting function for operations such as usort() assert(Parity::compare(1, 2) < 0); // The following methods are convenience methods, implemented on top of compare(). assert(Parity::isEqualTo(1, 2) === false); assert(Parity::isNotEqualTo(1, 2) === true); assert(Parity::isNotEqualTo(1, 2) === true); assert(Parity::isLessThan(1, 2) === true); assert(Parity::isLessThanOrEqualTo(1, 2) === true); assert(Parity::isGreaterThan(1, 2) === false); assert(Parity::isGreaterThanOrEqualTo(1, 2) === false);
概念
可比较的
Parity 的核心概念是 可比较的。任何提供其与其他值比较行为的对象都是可比较的。比较引擎支持以下可比较概念的细化
- 受限可比较:可以查询其可以与之比较的值的可比较。
- 自我可比较:只能与完全相同类型的其他对象进行比较的可比较。
- 子类可比较:只能与同一类型或其派生类型的其他对象进行比较的可比较。
- 任何可比较:可以自由地与任何其他类型的值进行比较的可比较。
比较器
一个 比较器 定义了除自身之外值的比较行为。 Parity 提供以下比较器实现
- Parity 比较器:实现了上述部分中描述的可比较概念周围的逻辑。
- 深度比较器:执行数组和对象的深度比较。对象比较是递归安全的。
- 对象身份比较器:通过身份比较对象。
- 严格PHP比较器:对所有比较操作进行PHP严格比较的近似。
- PHP比较器:将标准的PHP比较行为作为Parity比较器暴露出来。
算法解决
Parity::compare($A, $B)
使用以下过程来确定使用哪个比较算法
如果满足以下条件,则使用$A->compare($B)
$A
是任何可比较的;或者$A
是受限制的可比较的,且$A->canCompare($B)
返回true
;或者$A
是自我可比较的,且$A
与$B
是相同类型;或者$A
是子类可比较的,且$B
是$A->compare()
实现的类的实例
如果上述条件都不满足,则尝试以相反的顺序进行比较,即将$A
放在右边,将$B
放在左边;结果也将被反转。如果仍然无法进行比较,Parity将回退到严格类型的深度比较。
在比较标量类型时,整数和双精度浮点数(PHP的唯一真实数值类型)被视为相同类型,因此表达式3 < 3.5 < 4
是正确的。数字字符串不是以这种方式进行比较。
注意事项
- 比较递归对象不是真正确定性的操作,因为对象是通过它们的对象哈希进行比较的,而更深入的比较可能会导致无限递归。