Skip to content

Commit ef0e447

Browse files
Your Namenikic
authored andcommitted
Add get_debug_type() function
RFC: https://wiki.php.net/rfc/get_debug_type
1 parent 8597ec0 commit ef0e447

File tree

5 files changed

+114
-0
lines changed

5 files changed

+114
-0
lines changed

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ PHP 8.0 UPGRADE NOTES
534534
. Added fdiv() function, which performs a floating-point division under
535535
IEEE 754 semantics. Division by zero is considered well-defined and
536536
will return one of Inf, -Inf or NaN.
537+
. Added get_debug_type() function, which returns a type useful for error
538+
messages. Unlike get_type(), it uses canonical type names, returns class
539+
names for objects, and indicates the resource type for resources.
540+
RFC: https://wiki.php.net/rfc/get_debug_type
537541

538542
- Zip:
539543
. ZipArchive::setMtimeName and ZipArchive::setMtimeIndex to set the

ext/standard/basic_functions.stub.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,9 @@ function socket_set_timeout($socket, int $seconds, int $microseconds = 0): bool
13821382
/** @param mixed $var */
13831383
function gettype($var): string {}
13841384

1385+
/** @param mixed $var */
1386+
function get_debug_type($var): string {}
1387+
13851388
function settype(&$var, string $type): bool {}
13861389

13871390
/** @param mixed $value */

ext/standard/basic_functions_arginfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gettype, 0, 1, IS_STRING, 0)
20512051
ZEND_ARG_INFO(0, var)
20522052
ZEND_END_ARG_INFO()
20532053

2054+
#define arginfo_get_debug_type arginfo_gettype
2055+
20542056
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_settype, 0, 2, _IS_BOOL, 0)
20552057
ZEND_ARG_INFO(1, var)
20562058
ZEND_ARG_TYPE_INFO(0, type, IS_STRING, 0)
@@ -2792,6 +2794,7 @@ ZEND_FUNCTION(stream_set_chunk_size);
27922794
ZEND_FUNCTION(stream_set_timeout);
27932795
#endif
27942796
ZEND_FUNCTION(gettype);
2797+
ZEND_FUNCTION(get_debug_type);
27952798
ZEND_FUNCTION(settype);
27962799
ZEND_FUNCTION(intval);
27972800
ZEND_FUNCTION(floatval);
@@ -3436,6 +3439,7 @@ static const zend_function_entry ext_functions[] = {
34363439
ZEND_FALIAS(socket_set_timeout, stream_set_timeout, arginfo_socket_set_timeout)
34373440
#endif
34383441
ZEND_FE(gettype, arginfo_gettype)
3442+
ZEND_FE(get_debug_type, arginfo_get_debug_type)
34393443
ZEND_FE(settype, arginfo_settype)
34403444
ZEND_FE(intval, arginfo_intval)
34413445
ZEND_FE(floatval, arginfo_floatval)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--TEST--
2+
Test get_debug_type() class reading
3+
--FILE--
4+
<?php
5+
6+
namespace Demo {
7+
class ClassInNamespace {
8+
9+
}
10+
}
11+
12+
namespace {
13+
class ClassInGlobal { }
14+
15+
class ToBeExtended { }
16+
interface ToBeImplemented { }
17+
18+
$fp = fopen(__FILE__, 'r');
19+
20+
$fp_closed = fopen(__FILE__, 'r');
21+
fclose($fp_closed);
22+
23+
/* tests against an object type */
24+
echo get_debug_type(new ClassInGlobal()) . "\n";
25+
echo get_debug_type(new Demo\ClassInNamespace()) . "\n";
26+
echo get_debug_type(new class {}) . "\n";
27+
echo get_debug_type(new class extends ToBeExtended {}) . "\n";
28+
echo get_debug_type(new class implements ToBeImplemented {}) . "\n";
29+
30+
/* scalars */
31+
echo get_debug_type("foo") . "\n";
32+
echo get_debug_type(false) . "\n";
33+
echo get_debug_type(true) . "\n";
34+
echo get_debug_type(1) . "\n";
35+
echo get_debug_type(1.1) . "\n";
36+
echo get_debug_type([]) . "\n";
37+
echo get_debug_type(null) . "\n";
38+
echo get_debug_type($fp) . "\n";
39+
echo get_debug_type($fp_closed) . "\n";
40+
41+
}
42+
43+
--EXPECT--
44+
ClassInGlobal
45+
Demo\ClassInNamespace
46+
class@anonymous
47+
ToBeExtended@anonymous
48+
ToBeImplemented@anonymous
49+
string
50+
bool
51+
bool
52+
int
53+
float
54+
array
55+
null
56+
resource (stream)
57+
resource (closed)

ext/standard/type.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,52 @@ PHP_FUNCTION(gettype)
3737
}
3838
/* }}} */
3939

40+
/* {{{ proto string get_debug_type(mixed var)
41+
Returns the type of the variable resolving class names */
42+
PHP_FUNCTION(get_debug_type)
43+
{
44+
zval *arg;
45+
const char *name;
46+
47+
ZEND_PARSE_PARAMETERS_START(1, 1)
48+
Z_PARAM_ZVAL(arg)
49+
ZEND_PARSE_PARAMETERS_END();
50+
51+
switch (Z_TYPE_P(arg)) {
52+
case IS_NULL:
53+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_NULL_LOWERCASE));
54+
case IS_FALSE:
55+
case IS_TRUE:
56+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_BOOL));
57+
case IS_LONG:
58+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_INT));
59+
case IS_DOUBLE:
60+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_FLOAT));
61+
case IS_STRING:
62+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_STRING));
63+
case IS_ARRAY:
64+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_ARRAY));
65+
case IS_OBJECT:
66+
if (Z_OBJ_P(arg)->ce->ce_flags & ZEND_ACC_ANON_CLASS) {
67+
name = ZSTR_VAL(Z_OBJ_P(arg)->ce->name);
68+
RETURN_NEW_STR(zend_string_init(name, strlen(name), 0));
69+
} else {
70+
RETURN_STR_COPY(Z_OBJ_P(arg)->ce->name);
71+
}
72+
case IS_RESOURCE:
73+
name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
74+
if (name) {
75+
RETURN_NEW_STR(zend_strpprintf(0, "resource (%s)", name));
76+
} else {
77+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_CLOSED_RESOURCE));
78+
}
79+
default:
80+
RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_UNKNOWN));
81+
}
82+
}
83+
/* }}} */
84+
85+
4086
/* {{{ proto bool settype(mixed &var, string type)
4187
Set the type of the variable */
4288
PHP_FUNCTION(settype)

0 commit comments

Comments
 (0)