Download the PHP package phpcommon/comparison without Composer

On this page you can find all versions of the php package phpcommon/comparison. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package comparison

PhpCommon Comparison

Build Status Code Coverage Scrutinizer Code Quality StyleCI Latest Stable Version Dependency Status

Latest release: 1.0.0-beta

PHP 5.4+ library to represent equivalence relations and strategies for hashing and sorting values.

Equivalence relations are useful to establish a generalized way for comparing values in respect to domain-specific requirements, as well as to represent custom criteria for comparing values into bounded contexts, specially for use in collections.

Complementary capabilities, such as hashing and sorting, are also covered by this library, making it a valuable addition to your development tool belt.

The API is extensively documented in the source code. In addition, an HTML version is also available for more convenient viewing in browser.

Installation

Use Composer to install the package:

Relations

A relation is a mathematical tool for describing associations between elements of sets. Relations are widely used in computer science, especially in databases and scheduling applications.

Unlike most modern languages, PHP does not support operator overloading, historically avoided as a design choice. In other words, it is not possible to override the default behaviour of native operators, such as equal, identical, greater than, less than, etc. For example, Java provides the Comparable interface, while Python provides some magic methods.

The importance of such concept become more evident in situations where the notion of equivalence or ordering varies according to the subject of comparison or to the context, as discussed in the following sections.

Equivalence

In mathematics, an equivalence relation is a binary relation that is reflexive, symmetric and transitive. In the computing field, however, there is another property that must be take into account: consistency. Consistency means that a relation should not produce different results for the same input.

A ubiquitous equivalence relation is the equality relation between elements of any set. Other examples includes:

For the purpose of this library, an equivalence relation can be generic or type-specific. Type-specific relations are defined by implementing either Equatable or Equivalence interfaces, while generic equivalences must implement the last one.

Equatable Objects

The Equatable interface defines a generalized method that a class implements to create a type-specific method for determining equality of instances.

To illustrate, considers a class Money, which aims to represent monetary values. This class is a good candidate for implementing the Equatable interface, because Money is a Value Object, that is, the notion of equality of those objects isn't based on identity. Instead, two instances of Money are equal if they have the same values. Thus, while Money::USD(5) === Money::USD(5) returns false, Money::USD(5)->equals(Money::USD(5)) returns true.

Here is the class previously mentioned:

Equivalence Relations

There are many cases, though, where having a non-standard, or external, way for comparing two values become necessary. Perhaps, the most obvious use case for those custom relations is for use with collections, but it is also useful for providing those capabilities to scalar values or an existing class that cannot provide it itself, because it belongs to a third-party package or built into PHP.

Suppose you are developing a software to help hospitals to manage blood donations. One of the requirements says that a nurse can not collect blood from donors who have the same blood type. A relation for this scenario would look like this:

This relation determines whether two people are of same blood group:

Since BloodGroupEquivalence establishes an equivalence relation between people based on their blood group, any attempt to add John to the collection will be ignored, because James is already present and they are of the same blood type.

It may look a bit complicated for a simple requirement at first, but in real cases it can be used to compare the equivalence among compatible blood types, in order to partition donors into groups.

Built-in Equivalence Relations

This library provides some generic equivalence relations as part of the standard library, as described below.

Identity Equivalence

Compares two values for identity.

This relation is based on the identical operator. Most of cases, two values are considered equivalent if they have the same type and value, but there are a few exceptions:

The following table summarizes how operands of the various types are compared:

$A \ $B NULL Boolean Integer Float String Resource Array Object
NULL true false false false false false false false
Boolean false $A === $B false false false false false false
Integer false false $A === $B false false false false false
Float false false false $A === $B false false false false
String false false false false $A === $B false false false
Resource false false false false false $A === $B false false
Array false false false false false false $A === $B false
Object false false false false false false false $A === $B

Value Equivalence

Compares two values for equality.

The value equivalence behaves exactly as the identity equivalence, except that it delegates comparison between Equatable objects to the objects being compared. Additionally, external relations can be specified for comparing values of a particular type. It is useful in cases where is desirable to override the default behaviour for a specific type, but keep all the others. It is also useful for defining a relation for objects of classes that belong to third-party packages or built into PHP.

The following rules are used to determine whether two values are considered equivalent:

The following table summarizes how operands of the various types are compared:

$A \ $B NULL Boolean Integer Float String Resource Array Object Equatable
NULL true false false false false false false false false
Boolean false $A === $B false false false false false false false
Integer false false $A === $B false false false false false false
Float false false false $A === $B false false false false false
String false false false false $A === $B false false false false
Resource false false false false false $A === $B false false false
Array false false false false false false eq($A, $B) false false
Object false false false false false false false $A === $B false
Equatable false false false false false false false false $A‑>equals($B)

Where eq() denotes a function that compares each pair of corresponding entries recursively, according to the rules described above.

This relation also provides a way to override the equivalence logic for a particular class without the need to create a new relation. For example, suppose you want to compare instances of \DateTime based on their values, but keep the default behaviour for the other types. It can be accomplished by specifying a custom relation to be used whenever an instance of \DateTime is compared against another value:

Semantic Equivalence

Compares two values for semantic equality.

A semantic equivalence is planned for future versions. It would allow the comparison of values that look semantically similar - even if they are of different types. It is similar to how loose comparison works in PHP, but under more restrictive conditions, in such a way that properties of reflexivity, symmetry and transitivity hold.

DateTime Value Equivalence

Compares two \DateTime instances based on their date, time and time zone.

This relation considers two instances of \DateTime to be equivalent if they have the same date, time and time zone:

Hashing

In PHP, array keys can be only represented as numbers and strings. However, there are several cases where storing complex types as keys is helpful. Take as example classes that represent different kinds of numbers or strings, such as GMP objects, Unicode strings, etc. It would be convenient to be able to use such objects as array keys too.

To fill this gap, this library introduces the interfaces Hashable and Hasher, which specify a protocol for providing hash codes for values. These interfaces does not require implementors to provide perfect hashing functions. That is, two values that are not equivalent may have the same hash code. However, to determine whether two values with the same hash code are, in fact, equal, the concepts of hashing and equivalence should be combined in a complementary way. It explains why Hasher and Hashable extends Equivalence and Equatable respectively.

A word of warning

A hash code is intended for efficient insertion and lookup in collections that are based on a hash table and for fast inequality checks. A hash code is not a permanent value. For this reason:

  • Do not serialize hash code values or store them in databases.
  • Do not use the hash code as the key to retrieve an object from a keyed collection.
  • Do not send hash codes across application domains or processes. In some cases, hash codes may be computed on a per-process or per-application domain basis.
  • Do not use the hash code instead of a value returned by a cryptographic hashing function if you need a cryptographically strong hash.
  • Do not test for equality of hash codes to determine whether two objects are equal, once unequal values can have identical hash codes.

Hashable

There are cases where it might be desirable to define a custom hashing logic for a class to best fit your requirements. For example, suppose you have a Point class to represent a 2D point:

A Point holds the x and y coordinates of a point. According to the definition of the class, two points are considered equal if they have the same coordinates. However, if you intend to store instances of Point in an hash-based map, for example, because you want to associate coordinates to labels, then you must ensure that your class produces hash codes that are coherent with the logic used for determining when two points are considered equal:

In that way, the getHash() method works in accordance to the equals() method, although the hashing algorithm may not be ideal. The implementation of efficient algorithms for hash code generation is beyond the scope of this guide. However, it is recommended to use a fast algorithm that produces reasonably different results for unequal values, and shift the heavy comparison logic to Equatable::equals().

Notice that hashable objects should either be immutable, or you need to exercise discipline in not changing them after they have been used in a hash-based structures.

Hasher

A Hasher provides hashing functionality for primitive types and objects of classes that do not implement Hashable.

The method hash() introduced by this interface is intended to provide a means for performing fast inequivalence checks and efficient insertion and lookup in hash-based data structures. This method is always coherent with equivalent(), which means that for any references $x and $y, if equivalent($x, $y), then hash($x) === hash($y). However, if equivalence($x, $y) evaluates to false, hash($x) === hash($y) may still be true. Hence why the hash() method is suitable for inequivalence checks, but not equivalence checks.

All implementations of Equivalence included in this library also provide hashing functionality. More information about how values are hashed can be found in the documentation of the respective implementation.

Sorting

Following the same logic of the concepts previously discussed, Comparable and Comparator are interfaces to provide natural and custom sorting strategies, respectively. Both interfaces specify a total order relation, a relation that is reflexive, antisymmetric and transitive.

Comparable

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the natural ordering of the class, and the method Comparable::compareTo() is referred to as its natural comparison method.

The following example shows how a class can define the natural order of its instances:

Comparator

The purpose of a Comparator is to allow you to define one or more comparison strategies that are not the natural comparison strategy for a class. Ideally, a Comparator must be implemented by a class different from the one it defines the comparison strategy for. If you want to define a natural comparison strategy for a class, you can implement Comparable instead.

Comparators can be passed to a sort method of a collection to allow precise control over its sort order. It can also be used to control the order of certain data structures, such as sorted sets or sorted maps. For example, consider the following comparator that orders strings according to their length:

This implementation represents one of many possible ways of sorting strings. Other strategies includes sorting alphabetically, lexicographically, etc.

Change log

Please see CHANGELOG for more information what has changed recently.

Testing

Check out the Test Documentation for more details.

Contributing

Contributions to the package are always welcome!

Please see CONDUCT for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

All contents of this package are licensed under the MIT license.


All versions of comparison with dependencies

PHP Build Version
Package Version
Requires php Version ^5.5|^7.0
phpcommon/intmath Version ~1.0@dev
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package phpcommon/comparison contains the following files

Loading the files please wait ....