Skip to content

Commit ff1f0f6

Browse files
committed
added Type::fromValue()
1 parent a570df6 commit ff1f0f6

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/Utils/Type.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace Nette\Utils;
1111

1212
use Nette;
13-
use function array_map, array_search, array_splice, count, explode, implode, is_a, is_string, strcasecmp, strtolower, substr, trim;
13+
use function array_map, array_search, array_splice, count, explode, implode, is_a, is_resource, is_string, strcasecmp, strtolower, substr, trim;
1414
use const PHP_VERSION_ID;
1515

1616

@@ -86,6 +86,23 @@ public static function fromString(string $type): self
8686
}
8787

8888

89+
/**
90+
* Creates a Type object based on the actual type of value.
91+
*/
92+
public static function fromValue(mixed $value): self
93+
{
94+
$type = get_debug_type($value);
95+
if (is_resource($value)) {
96+
$type = 'mixed';
97+
} elseif (str_ends_with($type, '@anonymous')) {
98+
$parent = substr($type, 0, -10);
99+
$type = $parent === 'class' ? 'object' : $parent;
100+
}
101+
102+
return new self([$type]);
103+
}
104+
105+
89106
/**
90107
* Resolves 'self', 'static' and 'parent' to the actual class name.
91108
*/

tests/Utils/Type.fromValue.phpt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Utils\Type::fromValue()
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Utils\Type;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
class Foo
16+
{
17+
}
18+
19+
interface Baz
20+
{
21+
}
22+
23+
Assert::same('int', (string) Type::fromValue(42));
24+
Assert::same('float', (string) Type::fromValue(3.14));
25+
Assert::same('string', (string) Type::fromValue('hello'));
26+
Assert::same('bool', (string) Type::fromValue(true));
27+
Assert::same('bool', (string) Type::fromValue(false));
28+
Assert::same('null', (string) Type::fromValue(null));
29+
Assert::same('array', (string) Type::fromValue([1, 2, 3]));
30+
Assert::same('Foo', (string) Type::fromValue(new Foo));
31+
Assert::same('stdClass', (string) Type::fromValue(new stdClass));
32+
Assert::same('Closure', (string) Type::fromValue(fn() => null));
33+
34+
// Anonymous class
35+
Assert::same('object', (string) Type::fromValue(new class {
36+
}));
37+
38+
Assert::same('Foo', (string) Type::fromValue(new class extends Foo {
39+
}));
40+
41+
Assert::same('Baz', (string) Type::fromValue(new class implements Baz {
42+
}));
43+
44+
// Resource
45+
Assert::same('mixed', (string) Type::fromValue(fopen('php://memory', 'r')));

0 commit comments

Comments
 (0)