Skip to content

Commit 5107cf9

Browse files
feature #226 [Php80] Add get_debug_type() (nicolas-grekas)
This PR was merged into the 1.15-dev branch. Discussion ---------- [Php80] Add get_debug_type() Waiting for - [ ] php/php-src#5143 - [ ] https://wiki.php.net/rfc/get_debug_type - [x] php/php-src#5153 Commits ------- 61168ea [Php80] Add get_debug_type()
2 parents 8f1b8e9 + 61168ea commit 5107cf9

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Polyfills are provided for:
4444
- the `get_mangled_object_vars`, `mb_str_split` and `password_algos` functions
4545
introduced in PHP 7.4;
4646
- the `fdiv` function introduced in PHP 8.0;
47+
- the `get_debug_type` function introduced in PHP 8.0;
4748
- the `preg_last_error_msg` function introduced in PHP 8.0;
4849
- the `str_contains` function introduced in PHP 8.0;
4950
- the `ValueError` class introduced in PHP 8.0;

src/Php80/Php80.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
/**
1515
* @author Ion Bazan <[email protected]>
1616
* @author Nico Oelgart <[email protected]>
17+
* @author Nicolas Grekas <[email protected]>
1718
*
1819
* @internal
1920
*/
@@ -24,6 +25,38 @@ public static function fdiv(float $dividend, float $divisor): float
2425
return @($dividend / $divisor);
2526
}
2627

28+
public static function get_debug_type($value): string
29+
{
30+
switch (true) {
31+
case null === $value: return 'null';
32+
case \is_bool($value): return 'bool';
33+
case \is_string($value): return 'string';
34+
case \is_array($value): return 'array';
35+
case \is_int($value): return 'int';
36+
case \is_float($value): return 'float';
37+
case \is_object($value): break;
38+
case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
39+
default:
40+
if (null === $type = @get_resource_type($value)) {
41+
return 'unknown';
42+
}
43+
44+
if ('Unknown' === $type) {
45+
$type = 'closed';
46+
}
47+
48+
return "resource ($type)";
49+
}
50+
51+
$class = \get_class($value);
52+
53+
if (false === strpos($class, '@')) {
54+
return $class;
55+
}
56+
57+
return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
58+
}
59+
2760
public static function preg_last_error_msg(): string
2861
{
2962
switch (preg_last_error()) {

src/Php80/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This component provides features added to PHP 8.0 core:
77
- [`fdiv`](https://php.net/fdiv)
88
- `ValueError` class
99
- `FILTER_VALIDATE_BOOL` constant
10+
- [`get_debug_type`](https://php.net/get_debug_type)
1011
- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
1112
- [`str_contains`](https://php.net/str_contains)
1213

src/Php80/bootstrap.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ function str_contains(string $haystack, string $needle): bool { return p\Php80::
2727
if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
2828
define('FILTER_VALIDATE_BOOL', FILTER_VALIDATE_BOOLEAN);
2929
}
30+
31+
if (!function_exists('get_debug_type')) {
32+
function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
33+
}
3034
}

tests/Php80/Php80Test.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,34 @@ public function invalidFloatProvider()
155155
);
156156
}
157157

158+
/**
159+
* @covers \Symfony\Polyfill\Php80\Php80::get_debug_type
160+
*/
161+
public function testGetDebugType()
162+
{
163+
$this->assertSame(__CLASS__, get_debug_type($this));
164+
$this->assertSame('stdClass', get_debug_type(new \stdClass()));
165+
$this->assertSame('class@anonymous', get_debug_type(eval('return new class() {};')));
166+
$this->assertSame('stdClass@anonymous', get_debug_type(eval('return new class() extends stdClass {};')));
167+
$this->assertSame('Reflector@anonymous', get_debug_type(eval('return new class() implements Reflector { function __toString() {} public static function export() {} };')));
168+
169+
$this->assertSame('string', get_debug_type('foo'));
170+
$this->assertSame('bool', get_debug_type(false));
171+
$this->assertSame('bool', get_debug_type(true));
172+
$this->assertSame('null', get_debug_type(null));
173+
$this->assertSame('array', get_debug_type(array()));
174+
$this->assertSame('int', get_debug_type(1));
175+
$this->assertSame('float', get_debug_type(1.2));
176+
$this->assertSame('resource (stream)', get_debug_type($h = fopen(__FILE__, 'r')));
177+
$this->assertSame('resource (closed)', get_debug_type(fclose($h) ? $h : $h));
178+
179+
$unserializeCallbackHandler = ini_set('unserialize_callback_func', null);
180+
$var = unserialize('O:8:"Foo\Buzz":0:{}');
181+
ini_set('unserialize_callback_func', $unserializeCallbackHandler);
182+
183+
$this->assertSame('__PHP_Incomplete_Class', get_debug_type($var));
184+
}
185+
158186
public function setExpectedException($exception, $message = '', $code = null)
159187
{
160188
if (!class_exists('PHPUnit\Framework\Error\Notice')) {

0 commit comments

Comments
 (0)