Skip to content

Commit 6419661

Browse files
Fix Comparator
Adds `getType` and `canCompare` methods and fix `compare` method Signed-off-by: Anton <[email protected]>
1 parent 97b6552 commit 6419661

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

src/Comparator.php

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,6 @@
55
use Closure;
66
use ReflectionFunction;
77

8-
use function abs;
9-
use function array_keys;
10-
use function count;
11-
use function ksort;
12-
use function get_class;
13-
use function get_object_vars;
14-
use function get_resource_type;
15-
use function gettype;
16-
use function in_array;
17-
use function is_nan;
18-
use function max;
19-
use function method_exists;
20-
use function min;
21-
use function strcasecmp;
22-
use function strcmp;
23-
use function stream_get_meta_data;
24-
25-
use const PHP_FLOAT_EPSILON;
26-
278
/**
289
* The flexible comparation.
2910
*/
@@ -74,6 +55,17 @@ class Comparator
7455
*/
7556
public const EQUAL_STREAM = 256;
7657

58+
/**
59+
* The alternative names of PHP types returning from `gettype()`.
60+
*/
61+
protected const ALT_TYPES = [
62+
'NULL' => 'null',
63+
'boolean' => 'bool',
64+
'integer' => 'int',
65+
'double' => 'float',
66+
'resource (closed)' => 'resource',
67+
];
68+
7769
/**
7870
* @var int The flags defines comparison behavior.
7971
*/
@@ -121,6 +113,37 @@ public function hasFlag(int $flag): bool
121113
return ($this->flags & $flag) === $flag;
122114
}
123115

116+
/**
117+
* Gets the PHP type of a variable.
118+
*
119+
* @param mixed $value the variable being type checked
120+
* @return string the type name
121+
*/
122+
public function getType($value): string
123+
{
124+
$type = gettype($value);
125+
126+
return static::ALT_TYPES[$type] ?? $type;
127+
}
128+
129+
/**
130+
* Checks whether PHP types are comparable (non-strict comparison).
131+
*
132+
* @param string $type the first type name
133+
* @param string $type2 the second type name
134+
*/
135+
public function canCompare(string $type, string $type2): bool
136+
{
137+
if (
138+
($type === 'object' && in_array($type2, ['int', 'float'], true))
139+
|| ($type2 === 'object' && in_array($type, ['int', 'float'], true))
140+
) {
141+
return false;
142+
}
143+
144+
return true;
145+
}
146+
124147
/**
125148
* Compares two values.
126149
*
@@ -132,31 +155,20 @@ public function compare($value, $value2): bool
132155
{
133156
if ($value === $value2) {
134157
return true;
135-
}
136-
137-
$type = gettype($value);
138-
$type2 = gettype($value2);
139-
if ($this->hasFlag(self::STRICT) && $type !== $type2) {
158+
} elseif ($this->hasFlag(self::STRICT)) {
140159
return false;
141160
}
142-
if (
143-
!$this->hasFlag(self::STRICT)
144-
&& $type === $type2
145-
&& $type !== 'array'
146-
&& $value == $value2
147-
) {
161+
162+
$type = $this->getType($value);
163+
$type2 = $this->gettype($value2);
164+
165+
if ($this->canCompare($type, $type2) && $value == $value2) {
148166
return true;
149167
}
150-
// TODO: fix non-strict comparation of non-compatible types (object with not object/string)
151168

152-
if ($type === 'double' || $type2 === 'double') {
153-
$type = 'float';
154-
} elseif ($type === 'string' || $type2 === 'string') {
155-
$type = 'string';
156-
}
157169
if (
158-
($type === $type2 && in_array($type, ['array', 'object', 'resource'], true))
159-
|| in_array($type, ['float', 'string'], true)
170+
$type === $type2
171+
&& in_array($type, ['array', 'object', 'resource', 'float', 'string'], true)
160172
) {
161173
return $this->{'compare' . $type . 's'}($value, $value2);
162174
}

0 commit comments

Comments
 (0)