Skip to content

Commit

Permalink
Fix Comparator
Browse files Browse the repository at this point in the history
Adds `getType` and `canCompare` methods and fix `compare` method

Signed-off-by: Anton <[email protected]>
  • Loading branch information
WinterSilence authored Aug 27, 2022
1 parent 97b6552 commit 6419661
Showing 1 changed file with 50 additions and 38 deletions.
88 changes: 50 additions & 38 deletions src/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,6 @@
use Closure;
use ReflectionFunction;

use function abs;
use function array_keys;
use function count;
use function ksort;
use function get_class;
use function get_object_vars;
use function get_resource_type;
use function gettype;
use function in_array;
use function is_nan;
use function max;
use function method_exists;
use function min;
use function strcasecmp;
use function strcmp;
use function stream_get_meta_data;

use const PHP_FLOAT_EPSILON;

/**
* The flexible comparation.
*/
Expand Down Expand Up @@ -74,6 +55,17 @@ class Comparator
*/
public const EQUAL_STREAM = 256;

/**
* The alternative names of PHP types returning from `gettype()`.
*/
protected const ALT_TYPES = [
'NULL' => 'null',
'boolean' => 'bool',
'integer' => 'int',
'double' => 'float',
'resource (closed)' => 'resource',
];

/**
* @var int The flags defines comparison behavior.
*/
Expand Down Expand Up @@ -121,6 +113,37 @@ public function hasFlag(int $flag): bool
return ($this->flags & $flag) === $flag;
}

/**
* Gets the PHP type of a variable.
*
* @param mixed $value the variable being type checked
* @return string the type name
*/
public function getType($value): string
{
$type = gettype($value);

return static::ALT_TYPES[$type] ?? $type;
}

/**
* Checks whether PHP types are comparable (non-strict comparison).
*
* @param string $type the first type name
* @param string $type2 the second type name
*/
public function canCompare(string $type, string $type2): bool
{
if (
($type === 'object' && in_array($type2, ['int', 'float'], true))
|| ($type2 === 'object' && in_array($type, ['int', 'float'], true))
) {
return false;
}

return true;
}

/**
* Compares two values.
*
Expand All @@ -132,31 +155,20 @@ public function compare($value, $value2): bool
{
if ($value === $value2) {
return true;
}

$type = gettype($value);
$type2 = gettype($value2);
if ($this->hasFlag(self::STRICT) && $type !== $type2) {
} elseif ($this->hasFlag(self::STRICT)) {
return false;
}
if (
!$this->hasFlag(self::STRICT)
&& $type === $type2
&& $type !== 'array'
&& $value == $value2
) {

$type = $this->getType($value);
$type2 = $this->gettype($value2);

if ($this->canCompare($type, $type2) && $value == $value2) {
return true;
}
// TODO: fix non-strict comparation of non-compatible types (object with not object/string)

if ($type === 'double' || $type2 === 'double') {
$type = 'float';
} elseif ($type === 'string' || $type2 === 'string') {
$type = 'string';
}
if (
($type === $type2 && in_array($type, ['array', 'object', 'resource'], true))
|| in_array($type, ['float', 'string'], true)
$type === $type2
&& in_array($type, ['array', 'object', 'resource', 'float', 'string'], true)
) {
return $this->{'compare' . $type . 's'}($value, $value2);
}
Expand Down

0 comments on commit 6419661

Please sign in to comment.